From 7095663db6e28fd6440ec7894fc789744c24c719 Mon Sep 17 00:00:00 2001 From: Nicholas openSUSE Software Engineer Date: Mon, 16 Sep 2024 20:23:29 -0300 Subject: [PATCH] [release-v2.9] 1st batch release 2.9.2 (#4452) Co-authored-by: rancherbot --- .../elemental-crd-104.2.0+up1.6.4.tgz | Bin 0 -> 19646 bytes .../elemental/elemental-104.2.0+up1.6.4.tgz | Bin 0 -> 3979 bytes .../rancher-logging-crd-104.1.1+up4.8.0.tgz | Bin 0 -> 170044 bytes .../rancher-logging-104.1.1+up4.8.0.tgz | Bin 0 -> 19602 bytes ...ancher-monitoring-crd-104.1.1+up57.0.3.tgz | Bin 0 -> 310389 bytes .../rancher-monitoring-104.1.1+up57.0.3.tgz | Bin 0 -> 479902 bytes .../elemental-crd/104.2.0+up1.6.4/Chart.yaml | 11 + .../104.2.0+up1.6.4/templates/crds.yaml | 3743 +++ .../validate-no-pending-deletions.yaml | 17 + charts/elemental/104.2.0+up1.6.4/Chart.yaml | 20 + charts/elemental/104.2.0+up1.6.4/README.md | 5 + .../elemental/104.2.0+up1.6.4/app-readme.md | 5 + .../elemental/104.2.0+up1.6.4/questions.yaml | 27 + .../104.2.0+up1.6.4/templates/_helpers.tpl | 17 + .../104.2.0+up1.6.4/templates/apiservice.yaml | 9 + .../104.2.0+up1.6.4/templates/capi_rbac.yaml | 10 + .../templates/channel-dev.yaml | 13 + .../104.2.0+up1.6.4/templates/channels.yaml | 30 + .../templates/cluster_role.yaml | 268 + .../templates/cluster_role_binding.yaml | 13 + .../104.2.0+up1.6.4/templates/deployment.yaml | 50 + .../104.2.0+up1.6.4/templates/globalrole.yaml | 16 + .../104.2.0+up1.6.4/templates/metadata.yaml | 10 + .../templates/serviceaccount.yaml | 4 + .../templates/validate-install-crd.yaml | 26 + charts/elemental/104.2.0+up1.6.4/values.yaml | 43 + .../104.1.1+up4.8.0/Chart.yaml | 10 + .../104.1.1+up4.8.0/README.md | 2 + ...xtensions.banzaicloud.io_eventtailers.yaml | 2467 ++ ...extensions.banzaicloud.io_hosttailers.yaml | 2651 ++ .../logging.banzaicloud.io_clusterflows.yaml | 2166 ++ ...logging.banzaicloud.io_clusteroutputs.yaml | 14812 +++++++++++ .../logging.banzaicloud.io_flows.yaml | 2150 ++ ...ogging.banzaicloud.io_fluentbitagents.yaml | 2535 ++ ...logging.banzaicloud.io_fluentdconfigs.yaml | 3240 +++ .../logging.banzaicloud.io_loggingroutes.yaml | 106 + .../logging.banzaicloud.io_loggings.yaml | 20601 ++++++++++++++++ .../logging.banzaicloud.io_nodeagents.yaml | 4788 ++++ .../logging.banzaicloud.io_outputs.yaml | 14078 +++++++++++ ...g.banzaicloud.io_syslogngclusterflows.yaml | 360 + ...banzaicloud.io_syslogngclusteroutputs.yaml | 2911 +++ ...ogging.banzaicloud.io_syslogngconfigs.yaml | 8104 ++++++ .../logging.banzaicloud.io_syslogngflows.yaml | 364 + ...ogging.banzaicloud.io_syslogngoutputs.yaml | 2905 +++ .../104.1.1+up4.8.0/.helmignore | 26 + .../104.1.1+up4.8.0/Chart.yaml | 30 + .../rancher-logging/104.1.1+up4.8.0/README.md | 134 + .../104.1.1+up4.8.0/app-readme.md | 45 + .../104.1.1+up4.8.0/templates/NOTES.txt | 0 .../templates/_generic_fluentbitagent.yaml | 82 + .../templates/_generic_logging.yaml | 72 + .../104.1.1+up4.8.0/templates/_helpers.tpl | 197 + .../templates/clusterrole.yaml | 388 + .../templates/clusterrolebinding.yaml | 18 + .../104.1.1+up4.8.0/templates/crds.yaml | 6 + .../104.1.1+up4.8.0/templates/deployment.yaml | 79 + .../templates/extra-manifests.yaml | 4 + .../templates/logging/clusterflows.yaml | 14 + .../templates/logging/clusteroutputs.yaml | 14 + .../templates/logging/eventtailer.yaml | 41 + .../templates/logging/fluentbit.yaml | 17 + .../templates/logging/hosttailer.yaml | 31 + .../templates/logging/logging.yaml | 60 + .../loggings/aks/fluentbitagent.yaml | 17 + .../templates/loggings/aks/logging.yaml | 7 + .../loggings/eks/fluentbitagent.yaml | 18 + .../templates/loggings/eks/logging.yaml | 17 + .../loggings/gke/fluentbitagent.yaml | 17 + .../templates/loggings/gke/logging.yaml | 7 + .../templates/loggings/k3s/configmap.yaml | 57 + .../templates/loggings/k3s/daemonset.yaml | 110 + .../loggings/k3s/fluentbitagent.yaml | 18 + .../loggings/k3s/logging-k3s-openrc.yaml | 7 + .../loggings/kube-audit/fluentbitagent.yaml | 21 + .../loggings/kube-audit/logging.yaml | 11 + .../templates/loggings/rke/configmap.yaml | 29 + .../templates/loggings/rke/daemonset.yaml | 122 + .../templates/loggings/rke2/configmap.yaml | 69 + .../templates/loggings/rke2/daemonset.yaml | 116 + .../loggings/root/fluentbitagent.yaml | 29 + .../templates/loggings/root/logging.yaml | 67 + .../104.1.1+up4.8.0/templates/service.yaml | 20 + .../templates/service_monitor.yaml | 30 + .../templates/serviceaccount.yaml | 14 + .../templates/test_receiver.yaml | 53 + .../104.1.1+up4.8.0/templates/userrole.yaml | 39 + .../104.1.1+up4.8.0/templates/userroles.yaml | 35 + .../templates/validate-install-crd.yaml | 29 + .../templates/validate-install.yaml | 5 + .../templates/validate-psp-install.yaml | 7 + .../values-logging-example.yaml | 24 + .../104.1.1+up4.8.0/values.yaml | 484 + .../104.1.1+up57.0.3/Chart.yaml | 10 + .../104.1.1+up57.0.3/README.md | 24 + .../104.1.1+up57.0.3/files/crd-manifest.tgz | Bin 0 -> 308563 bytes .../104.1.1+up57.0.3/templates/_helpers.tpl | 30 + .../104.1.1+up57.0.3/templates/jobs.yaml | 102 + .../104.1.1+up57.0.3/templates/manifest.yaml | 8 + .../104.1.1+up57.0.3/templates/rbac.yaml | 76 + .../templates/validate-psp-install.yaml | 7 + .../104.1.1+up57.0.3/values.yaml | 17 + .../104.1.1+up57.0.3/.editorconfig | 5 + .../104.1.1+up57.0.3/.helmignore | 29 + .../104.1.1+up57.0.3/CHANGELOG.md | 47 + .../104.1.1+up57.0.3/CONTRIBUTING.md | 12 + .../104.1.1+up57.0.3/Chart.yaml | 126 + .../104.1.1+up57.0.3/README.md | 1080 + .../104.1.1+up57.0.3/app-README.md | 46 + .../charts/grafana/.helmignore | 23 + .../charts/grafana/Chart.yaml | 39 + .../104.1.1+up57.0.3/charts/grafana/README.md | 770 + .../grafana/dashboards/custom-dashboard.json | 1 + .../charts/grafana/templates/NOTES.txt | 55 + .../charts/grafana/templates/_config.tpl | 171 + .../charts/grafana/templates/_helpers.tpl | 305 + .../charts/grafana/templates/_pod.tpl | 1296 + .../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 | 15 + .../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 | 131 + .../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 | 61 + .../grafana/templates/serviceaccount.yaml | 17 + .../grafana/templates/servicemonitor.yaml | 68 + .../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 | 1315 + .../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 | 314 + .../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 | 49 + .../templates/serviceaccount.yaml | 17 + .../templates/servicemonitor.yaml | 126 + .../templates/stsdiscovery-role.yaml | 26 + .../templates/stsdiscovery-rolebinding.yaml | 17 + .../templates/verticalpodautoscaler.yaml | 44 + .../charts/kube-state-metrics/values.yaml | 491 + .../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 | 28 + .../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-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 | 143 + .../external-metrics-apiservice.yaml | 34 + ...rnal-metrics-cluster-role-binding-hpa.yaml | 20 + .../external-metrics-cluster-role.yaml | 21 + .../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 | 27 + .../templates/serviceaccount.yaml | 18 + .../charts/prometheus-adapter/values.yaml | 277 + .../prometheus-node-exporter/.helmignore | 21 + .../prometheus-node-exporter/Chart.yaml | 25 + .../charts/prometheus-node-exporter/README.md | 97 + .../templates/NOTES.txt | 29 + .../templates/_helpers.tpl | 236 + .../templates/clusterrole.yaml | 19 + .../templates/clusterrolebinding.yaml | 20 + .../templates/daemonset.yaml | 309 + .../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 | 29 + .../templates/serviceaccount.yaml | 17 + .../templates/servicemonitor.yaml | 71 + .../templates/verticalpodautoscaler.yaml | 40 + .../prometheus-node-exporter/values.yaml | 530 + .../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 + .../104.1.1+up57.0.3/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 + .../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 + .../104.1.1+up57.0.3/templates/NOTES.txt | 4 + .../104.1.1+up57.0.3/templates/_helpers.tpl | 459 + .../templates/alertmanager/alertmanager.yaml | 191 + .../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 | 35 + .../templates/alertmanager/service.yaml | 68 + .../alertmanager/serviceaccount.yaml | 21 + .../alertmanager/servicemonitor.yaml | 84 + .../alertmanager/serviceperreplica.yaml | 49 + .../templates/exporters/core-dns/service.yaml | 24 + .../exporters/core-dns/servicemonitor.yaml | 58 + .../kube-api-server/servicemonitor.yaml | 57 + .../kube-controller-manager/endpoints.yaml | 22 + .../kube-controller-manager/service.yaml | 29 + .../servicemonitor.yaml | 69 + .../templates/exporters/kube-dns/service.yaml | 28 + .../exporters/kube-dns/servicemonitor.yaml | 71 + .../exporters/kube-etcd/endpoints.yaml | 20 + .../exporters/kube-etcd/service.yaml | 27 + .../exporters/kube-etcd/servicemonitor.yaml | 75 + .../exporters/kube-proxy/endpoints.yaml | 20 + .../exporters/kube-proxy/service.yaml | 27 + .../exporters/kube-proxy/servicemonitor.yaml | 63 + .../exporters/kube-scheduler/endpoints.yaml | 22 + .../exporters/kube-scheduler/service.yaml | 29 + .../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 | 58 + .../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 | 17 + .../mutatingWebhookConfiguration.yaml | 77 + .../validatingWebhookConfiguration.yaml | 77 + .../prometheus-operator/certmanager.yaml | 55 + .../ciliumnetworkpolicy.yaml | 40 + .../prometheus-operator/clusterrole.yaml | 109 + .../clusterrolebinding.yaml | 16 + .../prometheus-operator/deployment.yaml | 204 + .../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 | 57 + .../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 | 30 + .../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 | 472 + .../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 | 55 + .../kubernetes-system-kube-proxy.yaml | 56 + .../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 | 707 + .../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 | 80 + .../prometheus/serviceThanosSidecar.yaml | 39 + .../serviceThanosSidecarExternal.yaml | 46 + .../templates/prometheus/serviceaccount.yaml | 21 + .../templates/prometheus/servicemonitor.yaml | 97 + .../servicemonitorThanosSidecar.yaml | 55 + .../templates/prometheus/servicemonitors.yaml | 47 + .../prometheus/serviceperreplica.yaml | 54 + .../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 + .../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 | 147 + .../rancher-monitoring/upgrade/configmap.yaml | 13 + .../rancher-monitoring/upgrade/job.yaml | 46 + .../rancher-monitoring/upgrade/rbac.yaml | 131 + .../templates/thanos-ruler/extrasecret.yaml | 20 + .../templates/thanos-ruler/ingress.yaml | 77 + .../thanos-ruler/podDisruptionBudget.yaml | 21 + .../templates/thanos-ruler/ruler.yaml | 189 + .../templates/thanos-ruler/secret.yaml | 26 + .../templates/thanos-ruler/service.yaml | 53 + .../thanos-ruler/serviceaccount.yaml | 20 + .../thanos-ruler/servicemonitor.yaml | 82 + .../templates/validate-install-crd.yaml | 23 + .../templates/validate-psp-install.yaml | 7 + .../104.1.1+up57.0.3/values.yaml | 5431 ++++ index.yaml | 231 + regsync.yaml | 9 + release.yaml | 18 +- 673 files changed, 196667 insertions(+), 6 deletions(-) create mode 100644 assets/elemental-crd/elemental-crd-104.2.0+up1.6.4.tgz create mode 100644 assets/elemental/elemental-104.2.0+up1.6.4.tgz create mode 100644 assets/rancher-logging-crd/rancher-logging-crd-104.1.1+up4.8.0.tgz create mode 100644 assets/rancher-logging/rancher-logging-104.1.1+up4.8.0.tgz create mode 100644 assets/rancher-monitoring-crd/rancher-monitoring-crd-104.1.1+up57.0.3.tgz create mode 100644 assets/rancher-monitoring/rancher-monitoring-104.1.1+up57.0.3.tgz create mode 100644 charts/elemental-crd/104.2.0+up1.6.4/Chart.yaml create mode 100644 charts/elemental-crd/104.2.0+up1.6.4/templates/crds.yaml create mode 100644 charts/elemental-crd/104.2.0+up1.6.4/templates/validate-no-pending-deletions.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/Chart.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/README.md create mode 100644 charts/elemental/104.2.0+up1.6.4/app-readme.md create mode 100644 charts/elemental/104.2.0+up1.6.4/questions.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/_helpers.tpl create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/apiservice.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/capi_rbac.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/channel-dev.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/channels.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/cluster_role.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/cluster_role_binding.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/deployment.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/globalrole.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/metadata.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/serviceaccount.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/templates/validate-install-crd.yaml create mode 100644 charts/elemental/104.2.0+up1.6.4/values.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/Chart.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/README.md create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging-extensions.banzaicloud.io_eventtailers.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging-extensions.banzaicloud.io_hosttailers.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_clusterflows.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_clusteroutputs.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_flows.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_fluentbitagents.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_fluentdconfigs.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_loggingroutes.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_loggings.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_nodeagents.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_outputs.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngclusterflows.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngclusteroutputs.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngconfigs.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngflows.yaml create mode 100644 charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngoutputs.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/.helmignore create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/Chart.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/README.md create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/app-readme.md create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/NOTES.txt create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/_generic_fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/_generic_logging.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/_helpers.tpl create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/clusterrole.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/clusterrolebinding.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/crds.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/deployment.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/extra-manifests.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/logging/clusterflows.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/logging/clusteroutputs.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/logging/eventtailer.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/logging/fluentbit.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/logging/hosttailer.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/logging/logging.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/aks/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/aks/logging.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/eks/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/eks/logging.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/gke/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/gke/logging.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/configmap.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/daemonset.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/logging-k3s-openrc.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/kube-audit/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/kube-audit/logging.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke/configmap.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke/daemonset.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke2/configmap.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke2/daemonset.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/root/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/root/logging.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/service.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/service_monitor.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/serviceaccount.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/test_receiver.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/userrole.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/userroles.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/validate-install-crd.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/validate-install.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/templates/validate-psp-install.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/values-logging-example.yaml create mode 100644 charts/rancher-logging/104.1.1+up4.8.0/values.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/Chart.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/README.md create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/files/crd-manifest.tgz create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/templates/jobs.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/templates/manifest.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/templates/rbac.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.1+up57.0.3/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/.editorconfig create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/CHANGELOG.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/CONTRIBUTING.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/app-README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/dashboards/custom-dashboard.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_config.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_pod.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/configSecret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/configmap-dashboard-provider.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/dashboards-json-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/extra-manifests.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/headless-service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/hpa.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-hpa.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-network-policy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/ingress.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/nginx-config.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/poddisruptionbudget.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/podsecuritypolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/pvc.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/secret-env.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/statefulset.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-podsecuritypolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/crs-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/extra-manifests.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/kubeconfig-secret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/pdb.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/podsecuritypolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/rbac-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/certmanager.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/pdb.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/daemonset.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/extra-manifests.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/podmonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/rbac-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/.helmignore create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/README.md create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/scripts/configure-firewall.ps1 create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/config.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/daemonset.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/podmonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/scriptConfig.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/values.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/ingress-nginx/nginx.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/ingress-nginx/request-handling-performance.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/cluster/rancher-cluster-nodes.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/cluster/rancher-cluster.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/bundle.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/bundledeployment.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/cluster.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/clustergroup.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/controller-runtime.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/gitrepo.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/home/rancher-default-home.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/k8s/rancher-etcd-nodes.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/k8s/rancher-etcd.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/k8s/rancher-k8s-components-nodes.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/k8s/rancher-k8s-components.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/nodes/rancher-node-detail.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/nodes/rancher-node.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/performance/performance-debugging.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/pods/rancher-pod-containers.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/pods/rancher-pod.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/workloads/rancher-workload-pods.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/workloads/rancher-workload.json create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/files/upgrade/scripts/delete-workloads-with-old-labels.sh create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/alertmanager.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/extrasecret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/ingress.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/ingressperreplica.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/podDisruptionBudget.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp-role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp-rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/serviceperreplica.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/core-dns/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/core-dns/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-api-server/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-dns/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-dns/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-etcd/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-etcd/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-etcd/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-proxy/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-proxy/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-proxy/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-scheduler/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-scheduler/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-scheduler/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-state-metrics/validate.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kubelet/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/node-exporter/validate.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/extra-objects.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/configmap-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/configmaps-datasources.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/alertmanager-overview.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/apiserver.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/cluster-total.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/controller-manager.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/etcd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/grafana-overview.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-coredns.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-node.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/kubelet.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-pod.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-workload.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/node-rsrc-use.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/nodes-darwin.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/nodes.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/pod-total.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/prometheus.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/scheduler.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/workload-total.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/namespaces.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/_prometheus-operator.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/certmanager.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/ciliumnetworkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp-clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp-clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/verticalpodautoscaler.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/_rules.tpl create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/additionalAlertRelabelConfigs.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/additionalAlertmanagerConfigs.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/additionalPrometheusRules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/additionalScrapeConfigs.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/ciliumnetworkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/csi-secret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/extrasecret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/ingress.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/ingressThanosSidecar.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/ingressperreplica.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/nginx-config.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/podDisruptionBudget.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/podmonitors.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/prometheus.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp-clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp-clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/alertmanager.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/config-reloaders.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/etcd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/general.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-state-metrics.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubelet.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-apps.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-resources.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-storage.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-exporter.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-exporter.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-network.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/prometheus-operator.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/prometheus.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/windows.node.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/windows.pod.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceThanosSidecar.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceThanosSidecarExternal.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/servicemonitorThanosSidecar.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/servicemonitors.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceperreplica.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/config-role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboard-role.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/hardened.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/job.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/extrasecret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/ingress.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/podDisruptionBudget.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/ruler.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/service.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.1+up57.0.3/values.yaml diff --git a/assets/elemental-crd/elemental-crd-104.2.0+up1.6.4.tgz b/assets/elemental-crd/elemental-crd-104.2.0+up1.6.4.tgz new file mode 100644 index 0000000000000000000000000000000000000000..7f87454fb04022d0e8a5bc43ac8363633372d36a GIT binary patch literal 19646 zcma&Nb9Cfg(=Hs_wr$&XCdR~?*tV^SC$^o5ZQHiZj`QWY@9#P9d;UAUR`;&jb?vKa z_xkl(U8|}HqoB}${`2~x2BI~TQf4xilIM`~;AS^sRcA6$VYkp$;pR|OSLcw|u(mX` zHSthYvg4OBwYCAe=zMd-qrBrv&-u`>|8?J)f--qxIJ|nYv4K}(`m6C)bXd6_aNqbY zpJrb;MLT`~U`Q?iU{$N~8_?Imq6aIo5*9r%QDz}v8Oc*5rrP!V&R;=UAC?F)A z&LQ2qskgqlxfyVAs`7ljwY7ET2k7!_0<3<{|I)wq`&gV0s_Fi;w)+}gRzwgG^~%5# z`#Dj)iKyzV&y(@KPNkL$yb63^>y#Zg8W?47<1`+k zL@|;^BHKc;CSwur(1k!5GAWAi1+HbF$LTa;fe*}x1rzWGYGfR^1lVlKx~c_)cQM@$8jtfNTSR@_9{gbNuSLStn5QWASOR|kn3}Nwb0}Bs80p%NJEga%&l4 z9ICgIM8?QQ+_K#`S3xrDiQJ)H;YnYq&T&%ZZC_YMH+hT(gzI_hMu%CE^Xdv_P-cw~ z)iCqrk1B%{^XUC62`WhzrQmcOri%tK1pOG>kw+%*9;CD$lt8R zc^^im#aNROI2CmG=ewVQbbah6(4LfXggBn4bO{c?!ND*m$Yy-HYrr-1c*vkBd6#@N zm5$#(Hqt30ZNpb>%zJUA*-ruXHx)O@4U)C{81tC@($phaRN``}HKy=n!{|r{Ajoj) zXi39#sdxx(QmFHonvJx49jHE4PyOq;y#iMX#;IF z65-6~_WZK^aFe74#5X90P8kza(nd*!jY6mm3W<)u6i}U(0W#GN>EtHInY~|0dY%uF z_bUE|!+?y>e5>oLe8Avk$(v2^Xh}l2Z2t|YV31j+U%f{a`e-ZF&~RV-tGb{1q69(a){HCOyR!;CL$H@S9f2`+f>D_ zF0P>xF3p=>*Xx(>XBlmqo#hiMz>&@LWpn|6V&bMmL=_ae#XmiABFn$n$R{7YufjOO zUmvi|wDeD2A-Oidx73t=<|s^#TPPcFRCJ*+1(k7Z&KIX8+PXhcQ(u2%4vLZG8qjz} zVWdq;^9i45q9Vc#2sij)zQ$jigjR|i73 zkzr#GF*Z3~TA~_Uu7S>|7$o*|ym@Ts-a?ZP6-s#a>I*kawT-HC2}frJ|H0x=2{6%H z3iwdlzSPhpkw!~5n#8qWsKpPdX%SLzYAARq9a1nCen})>6I>BiX_q+%`|5ujmhM+A z72Ce3j8+*p=GGbXTy8>8Vx7~D4)R*R+i&zL-MPEud!2$ZJzJe``VhvJzkfiwbh(1_ zS)7)>_o0JIY2HSFkQp5|kT*XDDWO(pD<1<-HZH6)z_s)(3B4MgOOT8Uav^cgl+;Ez zVvR>TiI!0FEEkvH@{kY=9BI_c5?KcVxXRQXB^TjGrsT8hu3KEHakgnAwKxlH8yP~U zg%mO)lSyDrI?*wy1P`QZyZ(lREf8sSpf&^ifRWXMqhC^K1mXLEjd)kz?KV?48mUdM z#!`ufe1Y_lgE&3>g&XJh(PH{l$N715oYfzvulo7k^09f$Np2#KBCKWEzPObd>*CsO z2+5!#Ao`1hlJ^8%foxS+kfr5v4M|)xyUB$|qJZ^nZQ&04)%?r$t&3VFw~s!Kk!jak zy~q_E9ucIx!s9IBaElUI(d{R@Q1WQZ`kQyqDoS!8mgaS%C|PoG1{aFXmI1yNc$C|=lCuuW}z$P+cbCA88HTgQ5D^R{7Xf@e_)o`v1 z@`Xs1vXnSxD`J5ujKO0%j>4ktbH&7 z{_VY_4w=O!$kf`eN(s$v0?dff=x{aL``zfR zeXRKsH``hGGfPEyuQ-O^)}RcxLTjq(Hlx)INAORP-TMLwK~pJXIiawt-b)I3%kExP z)@mXcD=juGi>!Z%W<2^@@h*|?AdH$}Khp97cGXyvEi|=u{E0}DQh!_epgR2;+Fwni zN;`f2tE2h3241oVFs19!31c*WVGTmV7zq-nD5>5|H3?&4PQ-FWXKTN13;axsoD1F< z(O7(aNbJ*2GG9~pg0A7nO$D(Z~V=bF)8##Y?;n7X=}nPaTriRG>R(GDl?CTX|veB zEsgS!i3Rbzt%u8y=`(F*WHE9j-L4sJ$A6Ie6@bvxzA>#t54+}TFu{i~LhZTYa0k#< z_^>14aHBWlU)jNx8~~8lz8_!V8L2OB7Ex-w^#?n2h+%}$5zWA<<8;u=6BNC0Htv;B zT;EWv8h_v&&rLW{`MpMBU#@2^k)JL)&d!ora@DiIAXV(iIL7PhtPH7gyH-dW7&<7S zT(Uc{x;wIgWQx#jB+@J#?_SZ>Hz>DSlKQrz4=ICG{UR=1PU_>U?FDXOX2G7alYi#J zCaC%&e9oveZTO!ztWgK6P{6c0-{~}3Pj+JY5bj=$jT@hH4BdktikT3f!a0$6Z{E9r zFFL9+3vi7}Y#)*Dr7SnZ$W$Ct^-&z8M;EWqF)@=ShhKA}Cl!*0h-?6iH#zGh{a8&l zP^3T?hO_ySL>bA)*_sY4{k2}LsGKDV{k0%JQT;2xV=$&B@*S-Txj2?#%&O+xVPQBu zuGp@GG12LVm(I+iwfGoJs!C7)jN`6yZ$j0*-aen?DHd^1lFw{K7<;ko*Gh@ z`oUMEgxX*62M5s%Gc89%xwH&7pc8z_Kn7*%C^o`8nOfr@Ug^OdP`kyBcUC84dDud|`yhHjk z+`4QhE&LAh8Y|vrMQJFRuheDi6*zXB@+x@q#t3fb*RvTm1luLYN_CrTjw~9D30g5N zM1r5$-Tc~uh{b<#8mizMgUbB2n3ZKEV7#pe8r`KhlAIt7orP0|`ef!^j^T=En_X$3 zkZf1nF-@RjGN|ilKWOv{iCs=_EwN@hF@^*@KVQT8Ao9~#o~>P^zM$m1+D(WMcj3@A z?+JWMlGOVuw0(Pc_){PNp4|-QX3oV4J+YU1Kq|f>R_|$fHZZ(T)QReHlrNR8KgS}NTWR2%TrQ16TWVDusABc)r}WqQm!2W zRJa&uVqp?n)F13#-QMY+ z<*a^7b8>=Wvv6`O-zjRYnI`m+C0i8Y<5Pq)`}AD+LBeGwo|XSOyRPDs*rF(Dr)bAj zWE+IY`#NNo(KwpsSp8s=oJE$_Y0mCiy8CP=Z$tCe>2Hx#JB4Qy|Ln*)MPFYYTb{bJ zj^h0@&`!1yY#ReHytkSBxe07L<-faH-%ojY|u8n0f(d$%~cnG7Tw z9tcNXcJj$NP?Zrkeb6(dCr$)j1^>t#Q-|(w3V^p=%p<;J|XVtN2 zyQ^UwXbs(uwnrXYtliPL-&}(aZhsBF2>00UXOM-4x1601d?_v@&p><|DouHY7Gl$_ z<6wWRL)svm{ zn?=1%v>BWmuBJ!?Z}6?UtbJ3fg_u2wCyU;_^Fo21{)z}A4di!2u zV+RdYmoNBk~Y-Y>r1`0_~tV)8Qr=e9iCTq9B z3>jxFAU1@d>77o1LMhh3_S}unPLdBp8bi=?y+TE&oeQ5HW%s$rEnAw~Ax7vuzLN!K zS&d>L>YFabQ%pahk>xh?vk1|7lsrfD&~wI)o9#xMM^_28FXez4s}Et~yFzW&(JO!P z3&Fk(=eiy1>@`@M@V$?Qt@Y40^kau*o!~7jY3DOqizDcEpi!o; z07SKW!Q%FDPjViXFBTz~#wSo0RJHX4WiLA6HkgK|51P&?K+V2r{a0^t-ukJq50;Jx zmOg|A$L0Lan2isv3|Ej3p3d#P3za3{jjyGidK*%s1KPToF_@O~DdI#onji;Sqs^OA z=kzwORQ3F!i0a(sP4)X3#KAyxbkY#Otag6UYq_I-F=%lV?82(vNLCD`)$78p_BIm0 zskT<7Jw9w#Qnv%_Ql0;Obxcyz_Td?$0TjSI+`ZTz4s{XY-&5H@hrRf>>`}70NoMJ1 z{A6s!!|@^Dmjd%t;W%d9i(CfoD1ah8Cdt z(iNatTsU^yNl}*XLeO94Qz~a)%T%-sV#{z`+!kBlg<+uR9VBZ>1H(*g0{dd+xsLPW zC~%7M$sTS>-i4|$PXLM~k9d3mreUxk4Y~}3K$waz@xpJ8L9b$=shu7m$3B**B*fJ# zcl^C9D?Dsxi3RHBI5)R}2u6cpj5kkUrKSix9yl(ZBcGm%yu)-TS<|Z{SL`vay#(yy z5Q(rrekn7{X7B*9(6X&Z_>zB#P+9B4W&-7|?{n;>##hw+s@lOiZuLct51>AkV`qYX zDu40mhVQC=S}R$@*HVQf-JHZa9a7!15E)XLT1;ai_l(V81O|by$9vov!d#1ve1M6X zL}H_Pk=S7pXo_>k{bM{-6TZ`cpu2=*9(aPj2}d_-Pl2gJJtx{?#M19EH(znixy#4u zCi~0fYrO9`BoD8^?#p}<&gBm>S%eQk&CU>?q`|;QG9obRJ2FR{oCCvis1p7Y7mYe%`!PE!ZXR67fC!P$|D zRvWS_MjRwoa}j$;;H?BnNTd zc+kU9m{UyMX_gp2FXqZYnrG-jxbf0vj)HE92gfPFb7>;H)~!WW|_tsi2 zXcKAN_3J`TTBjYb6|cAH>l+_SJG`I$wtZrAC7fsN=f1_QAxJ|cO%{#=5X|u;xPj@& z?pOx(r|}i`ti0wU-khg*Y=9hj9DY5nsPS0bJBM21E}Fvpk^wA+i5GIM%nveCS!cBA zAfZ9$zx-j(ts-Cty_q|r^a4=TZBca3iEZ?@KseMTF&1gj?p`Fwkiyq zC7N{xds7l`OOLoI(-Ut;Kn}!TlO6CvzbJ@wCH^B)%Z|9A+-0#P=_NULCWZV596_Ix z#wb7C^r>>dTV{zlmF^PW2>R~ZD9|SXfO1O-kg)#2U(t(|#Ms1>O}O1nz?A;|=_(TQ zdHiaR)!H^2&-P1#^o}pmeM;3&ByE226{?08Tq{>wVYU$mV}Tm7WL({4CJO>**(jME z4sd^W%B|3Yk-5`^Y13`BxALmdn;`OcIyxbIfo?vaf}E>K(6U+)>CI-iR&6sN7#7xb zQj(;S5$u1GjfU&-DGJ8#b>CEsSiJ`a@j^ zz_IPuW$mEL3Gc!Nwq%JY?2K8q7fYsFRKeYIhN|4XLD}fihZC6>e&PKwM5B1G+yhoe z7#`91Pp0u^UC;>|I6`h{iEI0WZPWn*0(9=e63rH|917Uo*@v=ObeNe#H)U>>fTTzw zNyd>~=O8K7VF{@b*8FKNod&H?%BB6kQVqWERD;OOQdZD50h&BRnYh_(SR#m4%&7vY=QoDJ0k4ivU#A&o`tX{OW}f$`m%v~B?akt7nQuy8 zCF6_J|NC6FwIaEwya(WucCUuH4q z23eG-=Hgr3CDRJTvxxzt^NnuGmG{`ky3WrMIGn3OOkOJG#k|CZfVp1|s`=C~Mo*#4 zeYj?dueuZ+TS$wl6V|mVK-2#kf$7c?JR`xVFqvcP&43&m_dw^?NF#Tk=l6$B=4MgX zVx1p89rKj7X!;dN9>dm5$;Hve8Euq6?hXBi;o{b6oyt{KZie^AID-^((HNPsNKz&I zc1KP|9&h*i(s8U#f_q@>gm3*aVzRlP-L;<+ci_u(BRut@SM7?I&o1tLX26AQ1 zi3plFmXuDW^8AHkJtSSVpK3Qu+VI3`6t07TMYl|S$lQngV$82l8JO%x1oNO2a za6sH|GVG<`qL%llijv6z^w6V(l*W6Y;%9d{O|0!8`(R5sda6-l zWt!>DOkN-_ZYWhrk27SLd~OfY3yNCu%9yS2qvTsRAc>%(qjP>fy50TFBJT~=Imv4v z=zi9De)F^8buvFZ4EF)vhmp-9f4p=sNBhz!;$11*lz|(91mP`Ho{?UxM??ch74NN| z+9QzCa30%b#E_I>cxWDGH&56oK0|_^(fVNNz|7_lVtKbYzunqKGRULx{$d27CU3Z{ zjX+A_z5FO6?c~h({%bmLP5-=YCOBBX@BuN-5le1Q!PTxE9;Oni3oMer`S%4rU8s`HU)YsBJq;J+WjJQOLXVYxRe$stNFh_d_Y2{qjVEVfN)NvL8O;;6n5S9d=RWQc~lzI)}K;_vu{?s zMG0QDDYdAe)ybqeUDl<~<$w{Z5`vb+d#)RKDT@vPz+LHn6KgT7iQ#FD zWu}o#w@PSoaO(`YTglc7sbDh>O7UskF*BqA_v{DEihBv&5QzlG1!-nZJ|n6(+*LXS zHi*kigXM=dUO<)_*rG~>7T`<0r9nrilHSnBJ^2FX5N`L+7D|k$E}+knkao7DX7q75 znW$<(CSE=8FG^vuHuT)L*k*=Qm~8niO1cSax6)dKzzUPNkeyVri;l|7`PU2g&dAuO z$Lw;#DmCO&SPGq2*0i*=#Dx8p)XQ0$(NBN14R-BthJdsF+IuKU{o^p3C0@jlrqRZs z9Zv>MSVbMnAlGwniv_eA>_LR(e5Fpw*5ZLRhIki@f+Q}7ggSt@OC~&-hoBzCpUbf~ zeCgmMEcFC4e{iizvz4`67FtAjb_o_Y_k8dQjO`~&>_|W#!)7r+_bx+b7j|e!GTV- zI}0AUzW;<{RhW&PPH5fME5#{ zNp_gJIT09fs3f5ifkD>hzyE6n3;WbMu{`K(Bx+|ghV+_sVXbE;OzOiYK>z12od|mq zXg%oi=uxxcYf=x*5W{Y!{YGh8{}1tWKj|q2t^sKr8o=lN!{*QBg{+@GPrc~)1>sPW zsh;13#J~=5MDoQ=s7`^SlFIzD5blZ zTNp@Lr+>#qI;Gjg=t1b?z9zSx`j}HH!Oft~^~jr!8K8bvvOm0dYC*H+V_YRA+jr!ux>o6OO1CTot&vM^R3_nENuck9pEtj#vQx$5lR_EpO0J{-due}xt{ z^%47ZW0}tt?KCW9rM*T!;mRxa(}$wx4seu!8$MSeivd3&^JLkXwb~|8%!<;M0w=TE z4qmAkS>-$I4=$~p2)YRI>6TEa-cKGCt#L@?CZ~-{nqV;7HTdAt9RxPoGE90nM5a)n z_}DxicIFv|ea20I3uKH?6wC%O2_iPa zVfjj)et(-uB@R|7whPkf<#53gPG{4^+v&n%*e}EmRA9vE$I}pzre7Dl-|}-*ARh1W zhe<~D=gDOm=WA>vMa3EBuPH?XTE43-Xo=rdd1<77jnSEg8hS2RV|`~6-@)Zm6<|HQ z*sC*GMxmmhqf!J#I$C@0^)2FRq06Wk%~Jx-eU9@u4d|g{Ox(bRdmDI>55#W5rTlc~ zW-VnQWl6qU17@8jCQ`e2vsq*Z2@d%C7=ri0^-+k;<&fm(@mSJQUJq<-p`3?)kFR4I zb5I5zXT`izB<-E&T|?SMQc&d~J+5@{>dmt$(*EWEZ!NsBUEyYpV3e*rt@Xm14U^4T z{%n10o!9aY+OvN^+6RzJiK5mPu?(K*I`a=7qM4uv$%|1sPvR$gIN0MCla6zsmPr$$ z-#W`^x!H@UP_-Xmw(S8_J1MbqfMyt@1m9HElj-dB`Bw*gen_9Ww+B1eaPP!l7ZqsX zU&H7BUMzfld0Sl_E%WhOP~%zo>2JZfJO=RxdaL!6(`)|Bs~2nrQl&`Y(;XhV1U_b& z0S|Ss3l%msdC5uck1D#ib+`$wxA2xOGs!{VE94|!MUx117ttJDb+(>v&9=`)lGuBs z8mrlcuLK)8pGFDU9^F&-k7>)v4FV46KJKSWXMsnTNLrWzu8RH;r^DA~Yb(HI4Btp6J<>`QBSR z5jgy-%vz-xD!W%Pl9b4dfa;>akpSk0;^q_tIyv|pm|gOq66_S1A~1Ko<)z6+3^9RY zWJ9+6uo0Ow*@$O(q$T$2-plidW*ewlLqAO)kQg61ZO{d4E}N)W{P7GK&7WM%zyZ}o zM|HY8>Ow#k`HKtM_1V_&6qmJI`pxN;9vkU%jlLiI2aWHmv&;?Wws%O$!8s+Q;#b?( zMV9RD5kI%)?fesWceUuj5vXC5S7B;YRLikv1Nc zFRd#>D|{*~ACaZ8%q)C_Y-6hKcbQ0wva4Fa8a$?#6`SR&iiMBw#Ue*Ir&; z1={g}3IonN)v5CjgRv1!8q7dh#OHW6S@ea4PU`m_A{-KWym~O^IEfUHp2()4^}xgA zOh(>r=fmAuFLTD}hUptssj|#L#}yVe%j31}ll!V{8As|8Mml0NewfIz+U;2=!3`5! z$tzSThcx0G>c`F&)`T4X>)EXEAFf`fTd3MqZ&gF3<3D~te<>4Hb?%3W7nAKJNE~>e z-DbYDW@j&@Yi6Ws@1PB4C949s8K=)Tvn6~OH&doQrtdjx@Vn~@ER-48If-wQUkWkA zP*xynlguy+xz0To4^zd++^OCC=52i47)cjD_HQgmA%*z1&@sz+j}eGQLGChgMR&P|3_inu>o&?IWJ`7*dJg#`>P!(3` z;%gg5;DB)`f`q|tF56D;)Sg{U%CJYlua-K11}le~-omvE@5J$0S>q9$NLp!6n-IgT zy{Q{Xg?&)b+mKm8yusBy@E41UoxVQlM zZ<&b&KVfVPE^>-X7E_OT@;-MtS5^W{!!VqM3;vAijCbtJE;-i5=rS&CS^aC7oQw80 z4o*-bIc$Bsxzf#>VnnGhW+VOi)*fVT;=ntM)UGjT5678V@%Dh>wX617Ayxu6$c}pj zI~~M#Q(M~S%WZCC*%r)kAw_mW91|=0vDP%ISb1ysk0uQ9s%VYCY}WnHdY=5gQ!eRD z#Ah%OKr_o7JrEY-8YjoaG0J7a*|w@<+Ue2kN83G&_*g+M0f)VonX{NPIGKuG&>sXYJ_)mBK1OObIG_`2U$AyVM? z&g))}hj_rf=in(}gT{Mv-n5c$tlXC5vEF{yrqx38TinZ1yNxF;T+GuF4bNuyFLm7* zAMVY94bLj|EBYAcgdI4vA8h32G7IR$aAmZyREaRGi%oV+@lHs|$o?tPNEOwQvb zyeuCndcsxF6=|qtG?&HDvt;vsmw&R1gLM~EtCMNv2iZN%BA)6YkU%pF{F1upiJzE-kt^~yVh0FmY7J*O<)(3C2RBB9UlpvpSyX!og! zfkc)Gg(VZ{lZqp91SKAT#@_UtQUD$}j|Cv}h1SlvQP^ASt=#lYn`L=j>9n*+_U`!x z!zczAImLl|z^(B~UYLfMP|5n`DatD#vT)$VdT^s!S1i)WheoIz^OfD_?t4!`dpOtO)94r6xRL^&x4g7 z18AK=l5{r;J9o{%hxKv#BR>xJ*0nRm^)=$Yo8!b*qf-^a4_mXp8#M2wt|T(W$y89X zcNnQ#*E;tMzy!PUEt#9%`;Wqy(=Wta6U-(@4Z*q_$2LD<08n^LO2OV>$7|%yxQ|sr?7>)KO z)LbrYP89=$!NN#BEn+sNK-{hv*6R{uBqNs-!wakP`Q`cKaJ^w)W0-M!JAIJD)>>5Y zv&_L4c31%KEydW*ZG`Y@Vp|!E=;DszVur@)2DN(pMh>(%kkz1wu`W0F<}bRok`VTQ zV|jWb=4@|K38&U_2)K&6wYb<)fu1R*{K>vYt%ZE4qjUHv5*yNP>`9eg8X&@8yM!rIwawUM=H&LRRU}Lh%jcxw z2czT>Z^_6-Zh!F!O|_~sU5jeNw7B@R03kab4gB{zB!T z>WN79%j{O4Kk~L_pW0;gP`c1ebt$}_A4ZgvmN2T*J~5M=EL+iChzzO5{WDGlPw8F#9dx zCtg5?s4-B&GA!Oo-~JlfU+ng*It`6qCO&m+Gge5u3B8%t@MKr0)pp0nqM1$3l|hD> zz(6iDLwC&-^lzPJ1avww!R4c~a!&NBgzCCb#Tp7vwS8Y1loaU6C*VfezmMm$LW(Afe=m>8v|&!=n(U&>*NQ5$(m7b$MpASrHp4D8QA zPBD_5c*0(X%fiDUG(OSrX=vv*B0QU&dl6^q{L)d^SvZ8r+X6_7s|@jM@qFD0?tgbE zH3?kAbiX_wF1>(#-VQ#wt$#WAdAD|UHa_l#ac<{ib-YV8f87Tho`$@f3;rY=8IQ{r zYHIF2kBqsHi7{6y9@2@1ALAEQ;$DCg#Jt9@s}4bB!W<9fZ2aon`LlVZR~;K7!hEV6q-QNFD6U0esE&>k<<892U{kTr!*=HC8KF@Vs<9vr|OFbthG?nP6XWvxGS|4 zQRzCKN~kge&%6m&Es{bIaLj0J@e@K4JLY0A@StkEl&rA$^k3RTD6ooMK~~4dhAYXn z3oX}e|HrvAr{wboij!OvESca$+K#`%r)M)3lwY;oF=A6lDW(2f;#`PLvmmk$doQEY zC0|aj_xA;y!*;yo-G`A}#&;y5UN33Ib-<($F&L>70WirYk@ac%E(QZ(_L5xvD(N%X zGmcw7QRY0<4ElEC_BSq?(6;SY|^5ycF@9bt>fE!?=ZsIOZlD#-n%q$1n*ObVVfip;(_8 zhdCj+FwkI|MiyOAqRqwy56i>0>JJwVXAcX4m!g!8PddJg?pqGX@W!QGf&w5o$*fj4 z`2#3@_tl+6&$Xk1XRLo6Er~FQ6E6cuTs(qOp(qo0(Uh0y{PCwZjyZa(q7rI^E1@it zQ#&vs~0Jw@R%{jRFYOb>d*t=OG7H-gL?0gV$B%V z!Cg&2$kXZ8an=xDlE?-<5*A^OT!Tq8;Q3Mo>UFxHB8BDk5KG+o^V2?+D} z{}v55!#{Y1T7d9qfv;kn1#ZGAffIQa1Gf`87>17{7~zfbX{)M$^SmsCl3!AsfANP6 zW*mJ`Ne|C&G9>`^C8YI|jpu*1#o{#ZW_?7EhgA3F7{`1efhi>{Cmk+xm<|=YuAR#I z!{EZi4{123Hf}B{if;s7{Jklo$n{9LfvPtp4bYmHZ#3-T<&ABN78?@|scI3{l@no* zo`#jT3F};XbosJ{2KI+X1D?N$fDM4KVYk!LzbQPXuB}Ggg=W6$vSq>Pp=7} zAGLG>)_R;zlil*rsGbzpuX=3lVSl2Y7!*|`lSaE`<3-kq^2{LFz_9$?Jy?z}^!5{- zhcfhJk#;|O7%}lcrlC@Zvg#1zwVM_UKlX(tx%r0I0CV&iUvB+Cr8u0gZ!}PLu|3ed zR;`!DS`3yMoSqZm#HfK`1>{uV2}hhsfB z``xhTBP7fDli#b)XzVEW$66h-GeZQg7p8=aC!JD}Y%~96k3a7Xld{W4UzPwXSgZ`2 z=VdKVy`GcZc2=urJW&jN6@IYo9nwOpn{iqzT1M~57XuaO{k@uZ6(2VsZxWn>#=Lj8 zK$2e`COZEX-(~_3D(vi8?a-XvfYn#4;A>KQ{*X4TJ)|497a~%_KWhiaa^<^t)1plm zvR*59qX@cK_xHB|XJmbAQEOa)G?j4Sk?)dgBXm?oI*Mb&6?4GT; zv-qfNfDtTW5_Q@_B42*4;Cee#phh$d*Ht*Ub?nhCct1%biNsmF7CLE1K)m)TNNr;TzphKQ1i!xdEr3&N2UwGmEU>>z&Oxzp?Bnp_hNRa^|lD`2V|LLFUOkII?wJmo6+ zp^otjk%E0F91uJlXZpyEu1Ps^qkfe9c ztZJy9KM_h)7Wa9RLNy7O-m1|^pWcY-vo+M^niRs| zva@=!$)BsyXwRPK*1U1_P+8h*^egC9{h-FFGdUY}GpE{0MZ{GR{QTT02#Zwjk7R^u z(qkIC=hWY6*G)z~r5gPain~BptyyQbsfN}bW@_&S5vs1Y3$EZj*t};ExoR2c?}e(% z{-VDQG4DAy_=h(!nm*JZrpRqo3R2|s_nR?z@18&%isl9qmIg`WR!#OFYsmiqzeOAJ zZx9fw$Zac%$nC$TW!0dCcgVzaQL3)|Z&uoG#D6?eb^XKmEq;pa?*CV%{U&Wz|JKk= z{u==RS|S@J@A(4mo1p1mRzHG3ERoyA{}Vu!(|7P!rVRf?tU>$FvaI>dGWCsT2mGH< z{#U?N|Ip`Xgdj!Qaiz6G4=zuj#VOG-RjGtvAPtE(Zgu$lCYgeBvC`~Xa;f>9JPQli zHw)6@#UwBH4mSnW_sW+<*8e=fz9$#AwKc06$a~~<{=~xlYyb8+Gaxxcl_YLQAvb+6 zB4%8hRLs~DrkoIt+0H;X-e;E$uQX*~c7O+vLiLB}p&Xp1b;u$mKFbN>ONA(=YwsP+ zVCD9sxcg+Sz5T?89!H;4P9RxK2WQ&MsbY$2xw*VIwRf@*Fx0$2_#3Aw4$M^G2bw4@{$iOA4#LH)2qn!cH)coe7D#3-W4OVw37 zi^Tn-Ds<(D_lr$=g_MsyhXx*Gy*YwkIl1fo$oyO0=iHgo$ zNVgpBG^D;xJck`Yd~$RY-C#x@oo!ZA9QpLO_CC^n|9f$;S`kTD_J zL!!tGszMXqrRvR!!x{rAS#+Cp9Ey`7yVO8Ktry4;{)dRm)z&6P+502CwpAN1pAu4E z@a)UEvbZs&s(QyT0MT`3p?Z#|_sjmnVU7u%W|otecE1qibn%FFrLju1Bi}Lrj2Y16 zh5p^Re8u8+f5JB?HxvrB;|8xyE(4;@)d1QBzedA6~A4wEoT+lVMJXfloQ14s#(M*#V09$HEVmUd-{ zC3;X+UK7oMso!<3aUy!-n#rF&{LlXT+pnR0eL>q*zyJJ|_c*@U$4nL!Z1SoDpwv?k zbka3$T3(MUuepvv`TV)V<^jEL(-@+0n`XWR-F-jPb~Dh$)YG*L)kFlx8wwC=vXsZM5|x0eb?<$O5cv z4phs*GPZq@U51=X)?7Cy$Cy%)vZHY5lfEV+3IG5xJM(Bhtt72pqik*S)AoFuo5NxE z|7qZ2B}52)(Bt#jP$&CxbeOTJyTW_DYghW(a~FrRb|Gew?s(~Wa)UP}XJU@i*Af|# z7ahlDEP6=7N)TtM5T&^vVzlftK`|mx;45rS^b^BvBR>@-6Iari|;e7v}x!aZ&y=ua9o(v@BY*YxK zVs3dO5=$fo0L7akWqKlu@WRCZ%z2Kb*FsIIPl9p4MCrscI~d#Ay0r?D!(0=Rydjp7 z!|4rCME>|^(36#qk~!6NKzq-K?0eF4UphEhW+eDda!z1wvR4;`U9GNHXo79>teaW4 zgSU~&+px_a2RivItXjLKEN1aHd25gKoBw2Wk##nu=3jNM;P~hk0R%hUiG*ilN8urZ z72~KsG!pV?oNfsJYueLx9`rAG;(3>(3#98fHpD!XkZU2C>+i!%$7-ac=-S?2+IVcg zd>`+)7KioG`n(5L$&q28QEs^lx-n{_Bm=-`Nzm=z19t~>N_pWeJtj$E?igoo>R|Ys zKx<+PhzCY8X(ahcvWvM3EL&kEV-%bQLpEYY$)#P%v*PN)F;tPcDBHOTjMJc4d79Zi zWre$Os1DZffq%O6+?~iXpZjqd zYecB1$pXZiTxf7=rW_G04oqNp>Mocj6hY4UxudoHNrw>r_Txqn3(HE(UaQ7(z>wvk z3;KJyg>ZWp0|m6w0lnYkYG$~xYn#ceBKlsfHZH+5LJX!%|FM9?OKAabu+yOM95|#V zYdr-52qmo?ChhuPqI=-{p)^xk~nO&9zA713DDBi1#iWs0Q)pr*`X$ak# z`n_d;@#Q=$aG^Dy1 z-?O2H|Ehl9YFjA2BjY!`DhTdByyP0+JVfl@_MGSuynig;=ZwFBV<`W>Hb+RL|6`;R z?H|?j+p;9{?LRO&-s@lQ0==rF#DIh>!;#Jf^?#x|ofbtBy(;qj*ZcQnTo{M}bDb09 z|3qu~?}8)yjo13dAN}vE{P$Mn$^X#bl_NPa!b3W7wx(Y370g-U31TjfRy|r(#ZZ}W>5OBq5QC$ zEC3Y*R~IFRLF+G4=B$1Iz`a_i=S;<@3VD@-aLj?7?T=i8yj7Eszn z_Ba&Xm0(cph#w*7RTFuH$5joMX29#1BnJ?%t-ZF%xEBnGfxRV9)&`vxJ+F6uAp`ov zw;EFK=qP@Tryd!=1?z@DC#dUlqS_LVyw%-!D_^YYFtl# zZN`Ks>QzbcwKQav+Kk_O|KLJ`)%g8I`pTh>c*SA4^lghT(sn@s!76QBNVSClaM*YbU??i*+d{SPj__6#xJgqo}p<{!2G z+hRrj?O#~pzut2Ud{g3U$EKLbDlPxRCZ+j!OdS3#bpGpIN^_AX^_xcT2n9v`JKDy7 zmzZysGrDh>)BnE8Kj*)1zbNw$y@whUbVX=TYeuk|IM*!j?i&PIE6lBz==+x8tyk9i zBSim`cKnSBxlYZ82fv(Mqc1s+-HTKB7;gSuXlVyAjU6dry{p}Vfc6mqC1qB$9Hrol z!=HURT!L=SjpJQ`?us`Z6qF$U#!;d7lHh^iGTCrtz0<*KD>qN>=;WWB&q&pe_Elk4 z{5t10&395{gtHK{PzRf_Zhk6#(kn^=rR~ipq4W)-P5pS0RyV18D#|=Lw__SB z2vB4%I}D%PY_wKJO!Iw2Zi&arP5V(O$Xh!2WY^>ZOWl4W!-dxAG6O z2M#$@0!dX3@+aQoZGtn+i433f7Yv^DaPT+jzUQq!Bl-s^^F3_8SFadQKe)+-qac|! zTEb_O*iklE^?V7DZ)TaevK=UCnPn8e_p|C$VOBAZP0s?-jcH43cpgq;i?P@Y7i(|` zJg{XHjX<;-$NiYMSvk+0N@O+gT~fm_+FwcqD~KgGPqA|zz!Qoy?R{$@cloid*Qi_U zf%B|*a1a7B2Kds-V3Gm0@>;5Wv2=#& zY?Atjsy9Xt2ba+Gt7CGPF+bUEmkwjk{mk_pzC&@`*^24se?e6Oly~ zyRK)yon9c7`U})8G$0Z~UO|3kU#W>TkBVGP*LRTHN_GAfzBZT@Qjl*B2=wf%gv=FR z$;$y0wi+*Qh#-fa0X)Ah`_{&zY7g_?->hycFs-k;!j4muoBiWT69l3^ReQ`dz9{Es z#yk_SPqi>>RuF<|SMGjkVRJ}IAvfgas?XCK$v$t+6%((Qe5BsnAbk9)2~^cSk1yV0 z^s_2noT~C5zM_tI*+!6zn)_F3V%{eaAFu=$J%e+AKYEPI{({aH+Lxwd0J)_}(__0iIq2fwNubB@M#73vK|Ye?9K$-KUKPh`lK{Wx*nw4u;13^ND9&q@TyKK;_*E>ScNv1(-9%F0em-9^urha?!gp2!mkqLWsW7i~}jTd(Nq^f~PNv(xIpP{tpN;i^5rn53I zJ69WZvTgBGv`RjmABFD=t6YWjqc0Pzf1P*c6~6V>^S4_{bh>SqIg(#qFT7WIco9F~ z%uTS)&8J~h?Ii8;ID`c9bkr?A{X2cI1A{%SbNk=)0c@|P8zu0Mw$9ufzOeQ7W#T{E zdP4)~gv?p>{4{bcgH>nc3#S|9pig>OD#I99YO9>_c5@aA=2RlMw@ZZ`VHSRFA|B1T zMVG^U+&qK72^e-LExp}I;oH0V$rT=?fzm?n23sMrM=k(9Rx0w$E$l(^(+7AjQf3D> z3F+5f>Xq7ecVv0*#SAGYYRWAq$GLKt)|H*0QB2Nk>Wo@gW6j%$JcBfjTah7KwQ-** zFX*u}60$j53ZM&G!$iGJ;Ikji#Ot1ObEMqy7B_ehVvkjcF}hUff}Wt+Em7@De=~@6 zqXDYKWDh@161#NSF++4HO&Ryf*e`C0R|+`6>O&DvXP2EbpdutNQ>H7Kt){5xVnK0|eJ!|hc4U-`Rv%@%s1;&E=U9g`K1K`Az z({MqBCS0S*rlx&Zu7Xh{cz0-cK&4U_-gLwm;JwD$^fmS`RL2XNbwq!4Szj6r1QAeO zCF!FIrYxhBoGgh`ISB2)RqcC_$BQ|MRSw?g=S`^8eE{7BTeOD z*NoF)zSZ&yP;_a5k1QiH3HR6k1B&M@rN#H43m%O%m%~RBR_}^3AO+L!{9QC))Cw?` zES26i3mQmI>@77gWGSs*==}guxAeL*mX+L~?YMuyd{4>799IgKhzkwUI3op}tPugn zNgZ3tni~ShlcMb(#C`kQ9TC+A;^KzhEuW8HBgTEDy(qv%`4^Y9rW~_AxM*fucPr^C zGMJa4NA<%!-vi`9qRYjn?d0P!@fCWJ?;(i1m$rogTwanvlcR3wrgsjQO6u zuNLqB_q5_Wa)9CR<~-UdIqG_AKu}VZKO2bt4A5!8%;tH`$Qu^R$NB2{uvCPfBpjW ztRN^{8)@bJRx}k73c%5?)($X^7!10!V+=d6P23la6S>qwW%s&iG8FpKzx7k%jfAlC z(-cP`>HuJVxWotMI~Yd*{waZ3yB>|8$UN2?mf2=ZutnfO?&C`sMeY1awJ0=zcGo)K zlIcmqit)KqWuot{mi+AtNZ@OX+C?gtmwS&z*RH2rdu9+Uod6Ls@MZI0uqlFii$ofC zH8g#@LT5R!Punq&rW@Z*K&3QVxET?|`h&jg7rx1$rp&YPCrIK&2M3!d8_^oYg%Rvv W@j&yl^S@GM=QT31d{q3GsQv^mlpqKI literal 0 HcmV?d00001 diff --git a/assets/elemental/elemental-104.2.0+up1.6.4.tgz b/assets/elemental/elemental-104.2.0+up1.6.4.tgz new file mode 100644 index 0000000000000000000000000000000000000000..f9ed6f82b118273f6fac7bf9ef5f5b934c3a6493 GIT binary patch literal 3979 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 z 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т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%0Ax5?wjN=PaeP3`exC_)NoA7@NV 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']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + securityContext: + description: |- + SecurityContext holds security configuration that will be applied to a container. + Some fields are present in both SecurityContext and PodSecurityContext. When both + are set, the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + volumes: + items: + properties: + destination: + type: string + name: + type: string + source: + type: string + type: object + type: array + type: object + upgradeContainer: + description: ContainerSpec is a simplified container template. + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + envFrom: + items: + description: EnvFromSource represents the source of a set of + ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each key + in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + envs: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + securityContext: + description: |- + SecurityContext holds security configuration that will be applied to a container. + Some fields are present in both SecurityContext and PodSecurityContext. When both + are set, the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + volumes: + items: + properties: + destination: + type: string + name: + type: string + source: + type: string + type: object + type: array + type: object + required: + - drain + type: object + status: + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/part-of: Elemental Operator + app.kubernetes.io/version: '{{ .Chart.Version }}' + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: infrastructure-elemental + cluster.x-k8s.io/v1beta1: v1beta1 + release-name: '{{ .Release.Name }}' + name: managedosversionchannels.elemental.cattle.io +spec: + group: elemental.cattle.io + names: + kind: ManagedOSVersionChannel + listKind: ManagedOSVersionChannelList + plural: managedosversionchannels + singular: managedosversionchannel + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + deleteNoLongerInSyncVersions: + default: false + description: |- + DeleteNoLongerInSyncVersions automatically deletes + all no-longer-in-sync ManagedOSVersions that were created by this channel. + type: boolean + options: + x-kubernetes-preserve-unknown-fields: true + syncInterval: + default: 1h + type: string + type: + type: string + upgradeContainer: + description: ContainerSpec is a simplified container template. + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + envFrom: + items: + description: EnvFromSource represents the source of a set of + ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each key + in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + envs: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + securityContext: + description: |- + SecurityContext holds security configuration that will be applied to a container. + Some fields are present in both SecurityContext and PodSecurityContext. When both + are set, the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + volumes: + items: + properties: + destination: + type: string + name: + type: string + source: + type: string + type: object + type: array + type: object + type: object + status: + properties: + conditions: + description: Conditions describe the state of the managed OS version + object. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + failedSynchronizationAttempts: + description: FailedSynchronizationAttempts counts the number of consecutive + synchronization failures + type: integer + lastSyncedTime: + description: LastSyncedTime is the timestamp of the last synchronization + format: date-time + type: string + syncedGeneration: + description: SyncedGeneration tracks the spec generation of the last + synchronization + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/part-of: Elemental Operator + app.kubernetes.io/version: '{{ .Chart.Version }}' + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: infrastructure-elemental + cluster.x-k8s.io/v1beta1: v1beta1 + release-name: '{{ .Release.Name }}' + name: managedosversions.elemental.cattle.io +spec: + group: elemental.cattle.io + names: + kind: ManagedOSVersion + listKind: ManagedOSVersionList + plural: managedosversions + singular: managedosversion + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + metadata: + x-kubernetes-preserve-unknown-fields: true + minVersion: + type: string + type: + type: string + upgradeContainer: + description: ContainerSpec is a simplified container template. + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + envFrom: + items: + description: EnvFromSource represents the source of a set of + ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each key + in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + envs: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + securityContext: + description: |- + SecurityContext holds security configuration that will be applied to a container. + Some fields are present in both SecurityContext and PodSecurityContext. When both + are set, the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + volumes: + items: + properties: + destination: + type: string + name: + type: string + source: + type: string + type: object + type: array + type: object + version: + type: string + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/part-of: Elemental Operator + app.kubernetes.io/version: '{{ .Chart.Version }}' + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: infrastructure-elemental + cluster.x-k8s.io/v1beta1: v1beta1 + release-name: '{{ .Release.Name }}' + name: metadata.elemental.cattle.io +spec: + group: elemental.cattle.io + names: + kind: Metadata + listKind: MetadataList + plural: metadata + singular: metadata + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + annotations: + additionalProperties: + type: string + type: object + appVersion: + type: string + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/part-of: Elemental Operator + app.kubernetes.io/version: '{{ .Chart.Version }}' + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: infrastructure-elemental + cluster.x-k8s.io/v1beta1: v1beta1 + release-name: '{{ .Release.Name }}' + name: seedimages.elemental.cattle.io +spec: + group: elemental.cattle.io + names: + kind: SeedImage + listKind: SeedImageList + plural: seedimages + singular: seedimage + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + baseImage: + description: BaseImg the base elemental image used to build the seed + image. + type: string + buildContainer: + description: |- + BuildContainer settings for a custom container used to generate the + downloadable image. + properties: + args: + description: Args same as corev1.Container.Args + items: + type: string + type: array + command: + description: Command same as corev1.Container.Command + items: + type: string + type: array + image: + description: Image container image to run + type: string + imagePullPolicy: + description: Args same as corev1.Container.ImagePullPolicy + type: string + name: + description: Name of the spawned container + type: string + type: object + cleanupAfterMinutes: + default: 60 + description: |- + LifetimeMinutes the time at which the built seed image will be cleaned up. + If when the lifetime elapses the built image is being downloaded, the active + download will be completed before removing the built image. + Default is 60 minutes, set to 0 to disable. + format: int32 + type: integer + cloud-config: + description: CloudConfig contains cloud-config data to be put in the + generated iso. + x-kubernetes-preserve-unknown-fields: true + registrationRef: + description: MachineRegistrationRef a reference to the related MachineRegistration. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + retriggerBuild: + description: RetriggerBuild triggers to build again a cleaned up seed + image. + type: boolean + size: + anyOf: + - type: integer + - type: string + default: 6442450944 + description: |- + Size specifies the size of the volume used to store the image. + Defaults to 6Gi + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + targetPlatform: + description: 'Platform specifies the target platform for the built + image. Example: linux/amd64' + example: linux/amd64 + pattern: ^$|^\S+\/\S+$ + type: string + type: + default: iso + description: |- + Type specifies the type of seed image to built. + Valid values are iso|raw + Defaults to "iso" + enum: + - iso + - raw + type: string + required: + - registrationRef + - type + type: object + status: + properties: + conditions: + description: Conditions describe the state of the machine registration + object. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + downloadToken: + description: DownloadToken a token to identify the seed image to download. + type: string + downloadURL: + description: DownloadURL the URL from which the SeedImage can be downloaded + once built. + type: string + state: + description: State reflect the state of the seed image build process. + enum: + - Initialized + - Started + - Completed + - Failed + - NotStarted + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/elemental-crd/104.2.0+up1.6.4/templates/validate-no-pending-deletions.yaml b/charts/elemental-crd/104.2.0+up1.6.4/templates/validate-no-pending-deletions.yaml new file mode 100644 index 0000000000..6e16863118 --- /dev/null +++ b/charts/elemental-crd/104.2.0+up1.6.4/templates/validate-no-pending-deletions.yaml @@ -0,0 +1,17 @@ +{{- $crds := list + "machineinventories.elemental.cattle.io" + "machineinventoryselectors.elemental.cattle.io" + "machineinventoryselectortemplates.elemental.cattle.io" + "machineregistrations.elemental.cattle.io" + "managedosimages.elemental.cattle.io" + "managedosversionchannels.elemental.cattle.io" + "managedosversions.elemental.cattle.io" + "seedimages.elemental.cattle.io" + "metadata.elemental.cattle.io" +-}} +{{- range $index, $crd := $crds -}} + {{- $obj := lookup "apiextensions.k8s.io/v1" "CustomResourceDefinition" $.Release.Namespace $crd -}} + {{- if and $obj $obj.metadata.deletionTimestamp -}} + {{- required "CRDs from previous installations are pending to be removed (deletionTimestamp is set). Fully deleting them before (re-)installing is required" "" -}} + {{- end -}} +{{- end -}} diff --git a/charts/elemental/104.2.0+up1.6.4/Chart.yaml b/charts/elemental/104.2.0+up1.6.4/Chart.yaml new file mode 100644 index 0000000000..a88609bb6f --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/Chart.yaml @@ -0,0 +1,20 @@ +annotations: + catalog.cattle.io/auto-install: elemental-crd=match + catalog.cattle.io/certified: rancher + catalog.cattle.io/display-name: Elemental + catalog.cattle.io/kube-version: '>= 1.23.0-0' + catalog.cattle.io/namespace: cattle-elemental-system + catalog.cattle.io/os: linux + catalog.cattle.io/permits-os: linux + catalog.cattle.io/provides-gvr: elemental.cattle.io/v1beta1 + catalog.cattle.io/rancher-version: '>= 2.9.0-0 < 2.10.0-0' + catalog.cattle.io/release-name: elemental-operator + catalog.cattle.io/scope: management + catalog.cattle.io/type: cluster-tool + catalog.cattle.io/upstream-version: 1.6.4 +apiVersion: v2 +appVersion: 1.6.4 +description: Elemental provides Cloud Native OS Management for Cluster Nodes. +icon: https://raw.githubusercontent.com/rancher/elemental/main/logo/icon-elemental.svg +name: elemental +version: 104.2.0+up1.6.4 diff --git a/charts/elemental/104.2.0+up1.6.4/README.md b/charts/elemental/104.2.0+up1.6.4/README.md new file mode 100644 index 0000000000..bf7b83ea6c --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/README.md @@ -0,0 +1,5 @@ +# Elemental Operator Helm Chart + +This chart bootstraps an elemental-operator deployment on a [Rancher Manager](https://rancher.com/docs/rancher/) cluster using the [Helm](https://helm.sh) package manager. + +Check out the [Elemental Operator Helm Chart documentation](https://elemental.docs.rancher.com/elementaloperatorchart-reference/) in the official [Elemental guide](https://elemental.docs.rancher.com/). diff --git a/charts/elemental/104.2.0+up1.6.4/app-readme.md b/charts/elemental/104.2.0+up1.6.4/app-readme.md new file mode 100644 index 0000000000..3d694ac5f6 --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/app-readme.md @@ -0,0 +1,5 @@ +# Elemental + +Elemental brings to Rancher the ability to install and manage the OS of bare metal and virtualized machines. + +For more information on how to deploy an Elemental Cluster, follow the [official documentation](https://elemental.docs.rancher.com/). \ No newline at end of file diff --git a/charts/elemental/104.2.0+up1.6.4/questions.yaml b/charts/elemental/104.2.0+up1.6.4/questions.yaml new file mode 100644 index 0000000000..53a85c6e32 --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/questions.yaml @@ -0,0 +1,27 @@ +questions: +- variable: channel.defaultChannel + default: "true" + description: "Provide an Elemental OS Channel container image" + label: Elemental OS Channel + type: boolean + show_subquestion_if: true + group: "Elemental OS Channel" + subquestions: + - variable: channel.image + default: "registry.suse.com/rancher/elemental-channel/sl-micro" + description: "Specify the Elemental OS channel: for air-gapped scenarios you need to provide your own OS channel image (see https://elemental.docs.rancher.com/airgap for detailed instructions)" + type: string + label: Elemental OS Channel Image + group: "Elemental OS Channel" + - variable: channel.tag + default: "6.0-baremetal" + description: "Specify Elemental OS channel image tag" + type: string + label: "Elemental OS Channel Tag" + group: "Elemental OS Channel" +- variable: debug + default: "false" + description: "Enable debug logging in the Elemental operator" + type: boolean + label: "Enable Debug Logging" + group: "Logging" diff --git a/charts/elemental/104.2.0+up1.6.4/templates/_helpers.tpl b/charts/elemental/104.2.0+up1.6.4/templates/_helpers.tpl new file mode 100644 index 0000000000..ee1e6fe7d8 --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/_helpers.tpl @@ -0,0 +1,17 @@ +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- else -}} +{{- "" -}} +{{- end -}} +{{- end -}} + +{{- define "registry_url" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{ include "system_default_registry" . }} +{{- else if .Values.registryUrl -}} +{{- printf "%s/" .Values.registryUrl -}} +{{- else -}} +{{- "" -}} +{{- end -}} +{{- end -}} diff --git a/charts/elemental/104.2.0+up1.6.4/templates/apiservice.yaml b/charts/elemental/104.2.0+up1.6.4/templates/apiservice.yaml new file mode 100644 index 0000000000..73ae2e505f --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/apiservice.yaml @@ -0,0 +1,9 @@ +kind: APIService +apiVersion: management.cattle.io/v3 +metadata: + name: {{ .Release.Name }} +spec: + secretName: elemental-operator + secretNamespace: {{ .Release.Namespace }} + pathPrefixes: + - /elemental/ diff --git a/charts/elemental/104.2.0+up1.6.4/templates/capi_rbac.yaml b/charts/elemental/104.2.0+up1.6.4/templates/capi_rbac.yaml new file mode 100644 index 0000000000..8692f75269 --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/capi_rbac.yaml @@ -0,0 +1,10 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: elemental-capi-role + labels: + cluster.x-k8s.io/aggregate-to-manager: "true" +rules: + - apiGroups: ["elemental.cattle.io"] + resources: ["*"] + verbs: ["*"] diff --git a/charts/elemental/104.2.0+up1.6.4/templates/channel-dev.yaml b/charts/elemental/104.2.0+up1.6.4/templates/channel-dev.yaml new file mode 100644 index 0000000000..da66784034 --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/channel-dev.yaml @@ -0,0 +1,13 @@ +# Unstable channel for testing isv:Rancher:Elemental OBS projects +# it is only rendered if the registryUrl value includes a known OBS project reference +{{ if and (hasPrefix "registry.opensuse.org" .Values.registryUrl) (contains "isv/rancher/elemental" .Values.registryUrl) }} +apiVersion: elemental.cattle.io/v1beta1 +kind: ManagedOSVersionChannel +metadata: + name: unstable-testing-channel + namespace: fleet-default +spec: + options: + image: {{ .Values.registryUrl }}/rancher/elemental-unstable-channel:latest + type: custom +{{ end }} diff --git a/charts/elemental/104.2.0+up1.6.4/templates/channels.yaml b/charts/elemental/104.2.0+up1.6.4/templates/channels.yaml new file mode 100644 index 0000000000..c180d36d05 --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/channels.yaml @@ -0,0 +1,30 @@ +{{ $defChannelName := "" }} +{{ if and .Values.channel .Values.channel.image .Values.channel.tag .Values.channel.name }} +{{ $defChannelName := .Values.channel.name }} +apiVersion: elemental.cattle.io/v1beta1 +kind: ManagedOSVersionChannel +metadata: + name: {{ .Values.channel.name }} + namespace: fleet-default +spec: + options: + image: {{ .Values.channel.image }}:{{ .Values.channel.tag }} + type: custom +{{ end }} + +# Keep pre-existing channels managed by Helm if they do not match with the current default +# this way if an upgrade introduces a new channel any pre-existing channel managed by Helm is not deleted +{{ range $index, $channel := (lookup "elemental.cattle.io/v1beta1" "ManagedOSVersionChannel" "fleet-default" "").items }} + {{ if and (eq (index $channel.metadata.labels "app.kubernetes.io/managed-by") "Helm") (ne $channel.metadata.name $defChannelName) }} +--- +apiVersion: elemental.cattle.io/v1beta1 +kind: ManagedOSVersionChannel +metadata: + name: {{ $channel.metadata.name }} + namespace: fleet-default +spec: + options: + image: {{ $channel.spec.options.image }} + type: custom + {{ end }} +{{ end }} diff --git a/charts/elemental/104.2.0+up1.6.4/templates/cluster_role.yaml b/charts/elemental/104.2.0+up1.6.4/templates/cluster_role.yaml new file mode 100644 index 0000000000..aaa3a0f2ec --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/cluster_role.yaml @@ -0,0 +1,268 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: '{{ .Release.Name }}' +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - pods + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get +- apiGroups: + - "" + resources: + - pods/status + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - services/status + verbs: + - get +- apiGroups: + - cluster.x-k8s.io + resources: + - machines + verbs: + - get + - list + - watch +- apiGroups: + - elemental.cattle.io + resources: + - machineinventories + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - elemental.cattle.io + resources: + - machineinventories/status + verbs: + - get + - patch + - update +- apiGroups: + - elemental.cattle.io + resources: + - machineinventoryselectors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - elemental.cattle.io + resources: + - machineinventoryselectors/status + verbs: + - get + - list + - patch + - update +- apiGroups: + - elemental.cattle.io + resources: + - machineregistrations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - elemental.cattle.io + resources: + - machineregistrations/status + verbs: + - get + - patch + - update +- apiGroups: + - elemental.cattle.io + resources: + - managedosimages + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - elemental.cattle.io + resources: + - managedosimages/status + verbs: + - get + - list + - patch + - update +- apiGroups: + - elemental.cattle.io + resources: + - managedosversionchannels + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - elemental.cattle.io + resources: + - managedosversionchannels/status + verbs: + - get + - list + - patch + - update +- apiGroups: + - elemental.cattle.io + resources: + - managedosversions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - elemental.cattle.io + resources: + - managedosversions/status + verbs: + - get + - list + - patch + - update +- apiGroups: + - elemental.cattle.io + resources: + - seedimages + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - elemental.cattle.io + resources: + - seedimages/status + verbs: + - get + - patch + - update +- apiGroups: + - fleet.cattle.io + resources: + - bundles + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - management.cattle.io + resources: + - settings + verbs: + - get + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - roles + verbs: + - create + - delete + - list + - watch diff --git a/charts/elemental/104.2.0+up1.6.4/templates/cluster_role_binding.yaml b/charts/elemental/104.2.0+up1.6.4/templates/cluster_role_binding.yaml new file mode 100644 index 0000000000..e68c7bc96b --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/cluster_role_binding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }} +subjects: +- kind: ServiceAccount + name: {{ .Release.Name }} + namespace: {{.Release.Namespace}} + diff --git a/charts/elemental/104.2.0+up1.6.4/templates/deployment.yaml b/charts/elemental/104.2.0+up1.6.4/templates/deployment.yaml new file mode 100644 index 0000000000..576d58d596 --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/deployment.yaml @@ -0,0 +1,50 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app: elemental-operator + template: + metadata: + labels: + app: elemental-operator + spec: + containers: + - env: + - name: NO_PROXY + value: {{ .Values.noProxy }} + {{- if .Values.proxy }} + - name: HTTP_PROXY + value: {{ .Values.proxy }} + - name: HTTPS_PROXY + value: {{ .Values.proxy }} + {{- end }} + name: {{ .Release.Name }} + imagePullPolicy: "{{ .Values.image.imagePullPolicy }}" + image: {{ template "registry_url" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }} + args: + - operator + {{- if .Values.debug }} + - --v=5 + - --debug + {{- end }} + - --namespace + - {{ .Release.Namespace }} + - --operator-image + - {{ template "registry_url" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }} + - --seedimage-image + - {{ template "registry_url" . }}{{ .Values.seedImage.repository }}:{{ .Values.seedImage.tag | default .Chart.AppVersion }} + - --seedimage-image-pullpolicy + - {{ .Values.seedImage.imagePullPolicy}} + serviceAccountName: {{ .Release.Name }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/elemental/104.2.0+up1.6.4/templates/globalrole.yaml b/charts/elemental/104.2.0+up1.6.4/templates/globalrole.yaml new file mode 100644 index 0000000000..323cf2ead8 --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/globalrole.yaml @@ -0,0 +1,16 @@ +apiVersion: management.cattle.io/v3 +builtin: false +description: "Elemental Administrator Role" +displayName: Elemental Administrator +kind: GlobalRole +metadata: + labels: + cattle.io/creator: norman + name: {{ .Release.Name }} +rules: +- apiGroups: + - elemental.cattle.io + resources: + - '*' + verbs: + - '*' diff --git a/charts/elemental/104.2.0+up1.6.4/templates/metadata.yaml b/charts/elemental/104.2.0+up1.6.4/templates/metadata.yaml new file mode 100644 index 0000000000..d102d9f2ea --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/metadata.yaml @@ -0,0 +1,10 @@ +apiVersion: elemental.cattle.io/v1beta1 +kind: Metadata +metadata: + name: {{ .Release.Name }} +spec: + appVersion: {{ .Chart.AppVersion }} + annotations: + {{- range $key, $value := .Chart.Annotations }} + {{ $key }}: {{ toYaml $value }} + {{- end }} diff --git a/charts/elemental/104.2.0+up1.6.4/templates/serviceaccount.yaml b/charts/elemental/104.2.0+up1.6.4/templates/serviceaccount.yaml new file mode 100644 index 0000000000..cb203d6f6c --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/serviceaccount.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }} diff --git a/charts/elemental/104.2.0+up1.6.4/templates/validate-install-crd.yaml b/charts/elemental/104.2.0+up1.6.4/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..45008251ae --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/templates/validate-install-crd.yaml @@ -0,0 +1,26 @@ +{{ if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 }} + {{ $apis := dict + "elemental.cattle.io/v1beta1/MachineInventory" "machineinventories" + "elemental.cattle.io/v1beta1/MachineInventorySelector" "machineinventoryselectors" + "elemental.cattle.io/v1beta1/MachineInventorySelectorTemplate" "machineinventoryselectortemplates" + "elemental.cattle.io/v1beta1/MachineRegistration" "machineregistrations" + "elemental.cattle.io/v1beta1/ManagedOSImage" "managedosimages" + "elemental.cattle.io/v1beta1/ManagedOSVersionChannel" "managedosversionchannels" + "elemental.cattle.io/v1beta1/ManagedOSVersion" "managedosversions" + "elemental.cattle.io/v1beta1/SeedImage" "seedimages" + "elemental.cattle.io/v1beta1/Metadata" "metadata" + }} + {{- range $api, $crd := $apis -}} + {{- if not ($.Capabilities.APIVersions.Has $api) -}} + {{- required "Required CRDs are missing. Please install the corresponding CRD chart before installing this chart." "" -}} + {{- end -}} + {{- $crdobj := lookup "apiextensions.k8s.io/v1" "CustomResourceDefinition" "" (print $crd ".elemental.cattle.io") -}} + {{- if not $crdobj -}} + {{- print "Cannot lookup " $crd ".elemental.cattle.io crd object" | fail -}} + {{- end -}} + {{- $crdrelease := index $crdobj.metadata.annotations "meta.helm.sh/release-name" -}} + {{- if eq $crdrelease $.Release.Name -}} + {{- required "Elemental CRDs should be moved to the new elemental-operator-crds chart before upgrading this operator." "" -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/charts/elemental/104.2.0+up1.6.4/values.yaml b/charts/elemental/104.2.0+up1.6.4/values.yaml new file mode 100644 index 0000000000..1d32cc2f8a --- /dev/null +++ b/charts/elemental/104.2.0+up1.6.4/values.yaml @@ -0,0 +1,43 @@ +image: + empty: rancher/pause:3.1 + repository: "rancher/mirrored-elemental-operator" + tag: "1.6.4" + imagePullPolicy: IfNotPresent + +seedImage: + repository: "rancher/mirrored-elemental-seedimage-builder" + tag: "1.6.4" + imagePullPolicy: IfNotPresent + +channel: + name: "sl-micro-6.0-baremetal-channel" + image: "registry.suse.com/rancher/elemental-channel/sl-micro" + tag: "6.0-baremetal" + +# number of operator replicas to deploy +replicas: 1 + +# http[s] proxy server +# proxy: http://@:: + +# comma separated list of domains or ip addresses that will not use the proxy +noProxy: 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.svc,.cluster.local + +global: + cattle: + systemDefaultRegistry: "" + +# used only if systemDefaultRegistry is empty +registryUrl: "" + +# enable debug output for operator +debug: false + +nodeSelector: + kubernetes.io/os: linux + +tolerations: + - key: cattle.io/os + operator: "Equal" + value: "linux" + effect: NoSchedule diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/Chart.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/Chart.yaml new file mode 100644 index 0000000000..acddf1a0c5 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/Chart.yaml @@ -0,0 +1,10 @@ +annotations: + catalog.cattle.io/certified: rancher + catalog.cattle.io/hidden: "true" + catalog.cattle.io/namespace: cattle-logging-system + catalog.cattle.io/release-name: rancher-logging-crd +apiVersion: v1 +description: Installs the CRDs for rancher-logging. +name: rancher-logging-crd +type: application +version: 104.1.1+up4.8.0 diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/README.md b/charts/rancher-logging-crd/104.1.1+up4.8.0/README.md new file mode 100644 index 0000000000..d4beb54faf --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/README.md @@ -0,0 +1,2 @@ +# rancher-logging-crd +A Rancher chart that installs the CRDs used by rancher-logging. diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging-extensions.banzaicloud.io_eventtailers.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging-extensions.banzaicloud.io_eventtailers.yaml new file mode 100644 index 0000000000..eb2535fcdc --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging-extensions.banzaicloud.io_eventtailers.yaml @@ -0,0 +1,2467 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: eventtailers.logging-extensions.banzaicloud.io +spec: + group: logging-extensions.banzaicloud.io + names: + kind: EventTailer + listKind: EventTailerList + plural: eventtailers + singular: eventtailer + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + containerOverrides: + properties: + command: + items: + type: string + type: array + image: + type: string + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + pullPolicy: + type: string + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + controlNamespace: + type: string + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + positionVolume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + workloadMetaOverrides: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + workloadOverrides: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + containers: + items: + properties: + command: + items: + type: string + type: array + image: + type: string + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + pullPolicy: + type: string + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + type: array + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + command: + items: + type: string + type: array + image: + type: string + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + pullPolicy: + type: string + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + type: array + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + required: + - controlNamespace + type: object + status: + type: object + type: object + served: true + storage: true diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging-extensions.banzaicloud.io_hosttailers.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging-extensions.banzaicloud.io_hosttailers.yaml new file mode 100644 index 0000000000..d49355f12b --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging-extensions.banzaicloud.io_hosttailers.yaml @@ -0,0 +1,2651 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: hosttailers.logging-extensions.banzaicloud.io +spec: + group: logging-extensions.banzaicloud.io + names: + kind: HostTailer + listKind: HostTailerList + plural: hosttailers + singular: hosttailer + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + enableRecreateWorkloadOnImmutableFieldChange: + type: boolean + fileTailers: + items: + properties: + buffer_chunk_size: + type: string + buffer_max_size: + type: string + containerOverrides: + properties: + command: + items: + type: string + type: array + image: + type: string + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + pullPolicy: + type: string + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + disabled: + type: boolean + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + name: + type: string + path: + type: string + read_from_head: + type: boolean + skip_long_lines: + type: string + required: + - name + type: object + type: array + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + systemdTailers: + items: + properties: + containerOverrides: + properties: + command: + items: + type: string + type: array + image: + type: string + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + pullPolicy: + type: string + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + disabled: + type: boolean + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + maxEntries: + type: integer + name: + type: string + path: + type: string + systemdFilter: + type: string + required: + - name + type: object + type: array + workloadMetaOverrides: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + workloadOverrides: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + containers: + items: + properties: + command: + items: + type: string + type: array + image: + type: string + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + pullPolicy: + type: string + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + type: array + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + command: + items: + type: string + type: array + image: + type: string + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + pullPolicy: + type: string + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + type: array + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + status: + type: object + type: object + served: true + storage: true diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_clusterflows.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_clusterflows.yaml new file mode 100644 index 0000000000..2d0586cc66 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_clusterflows.yaml @@ -0,0 +1,2166 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: clusterflows.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: ClusterFlow + listKind: ClusterFlowList + plural: clusterflows + singular: clusterflow + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the flow active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + filters: + items: + properties: + concat: + properties: + continuous_line_regexp: + type: string + flush_interval: + type: integer + keep_partial_key: + type: boolean + keep_partial_metadata: + type: string + key: + type: string + multiline_end_regexp: + type: string + multiline_start_regexp: + type: string + n_lines: + type: integer + partial_cri_logtag_key: + type: string + partial_cri_stream_key: + type: string + partial_key: + type: string + partial_metadata_format: + type: string + partial_value: + type: string + separator: + type: string + stream_identity_key: + type: string + timeout_label: + type: string + use_first_timestamp: + type: boolean + use_partial_cri_logtag: + type: boolean + use_partial_metadata: + type: string + type: object + dedot: + properties: + de_dot_nested: + type: boolean + de_dot_separator: + type: string + type: object + detectExceptions: + properties: + force_line_breaks: + type: boolean + languages: + items: + type: string + type: array + match_tag: + type: string + max_bytes: + type: integer + max_lines: + type: integer + message: + type: string + multiline_flush_interval: + type: string + remove_tag_prefix: + type: string + stream: + type: string + type: object + elasticsearch_genid: + properties: + hash_id_key: + type: string + hash_type: + type: string + include_tag_in_seed: + type: boolean + include_time_in_seed: + type: boolean + record_keys: + type: string + separator: + type: string + use_entire_record: + type: boolean + use_record_as_seed: + type: boolean + type: object + enhanceK8s: + properties: + api_groups: + items: + type: string + type: array + bearer_token_file: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cache_refresh: + type: integer + cache_refresh_variation: + type: integer + cache_size: + type: integer + cache_ttl: + type: integer + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + core_api_versions: + items: + type: string + type: array + data_type: + type: string + in_namespace_path: + items: + type: string + type: array + in_pod_path: + items: + type: string + type: array + kubernetes_url: + type: string + secret_dir: + type: string + ssl_partial_chain: + type: boolean + verify_ssl: + type: boolean + type: object + geoip: + properties: + backend_library: + type: string + geoip_database: + type: string + geoip_lookup_keys: + type: string + geoip2_database: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + skip_adding_null_record: + type: boolean + type: object + grep: + properties: + and: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + or: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + kube_events_timestamp: + properties: + mapped_time_key: + type: string + timestamp_fields: + items: + type: string + type: array + type: object + parser: + properties: + emit_invalid_record_to_error: + type: boolean + hash_value_field: + type: string + inject_key_prefix: + type: string + key_name: + type: string + parse: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + parsers: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + remove_key_name_field: + type: boolean + replace_invalid_sequence: + type: boolean + reserve_data: + type: boolean + reserve_time: + type: boolean + type: object + prometheus: + properties: + labels: + additionalProperties: + type: string + type: object + metrics: + items: + properties: + buckets: + type: string + desc: + type: string + key: + type: string + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: + type: string + required: + - desc + - name + - type + type: object + type: array + type: object + record_modifier: + properties: + char_encoding: + type: string + prepare_value: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + replaces: + items: + properties: + expression: + type: string + key: + type: string + replace: + type: string + required: + - expression + - key + - replace + type: object + type: array + whitelist_keys: + type: string + type: object + record_transformer: + properties: + auto_typecast: + type: boolean + enable_ruby: + type: boolean + keep_keys: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + renew_record: + type: boolean + renew_time_key: + type: string + type: object + stdout: + properties: + output_type: + type: string + type: object + sumologic: + properties: + collector_key_name: + type: string + collector_value: + type: string + exclude_container_regex: + type: string + exclude_facility_regex: + type: string + exclude_host_regex: + type: string + exclude_namespace_regex: + type: string + exclude_pod_regex: + type: string + exclude_priority_regex: + type: string + exclude_unit_regex: + type: string + log_format: + type: string + source_category: + type: string + source_category_key_name: + type: string + source_category_prefix: + type: string + source_category_replace_dash: + type: string + source_host: + type: string + source_host_key_name: + type: string + source_name: + type: string + source_name_key_name: + type: string + tracing_annotation_prefix: + type: string + tracing_container_name: + type: string + tracing_format: + type: boolean + tracing_host: + type: string + tracing_label_prefix: + type: string + tracing_namespace: + type: string + tracing_pod: + type: string + tracing_pod_id: + type: string + type: object + tag_normaliser: + properties: + format: + type: string + match_tag: + type: string + type: object + throttle: + properties: + group_bucket_limit: + type: integer + group_bucket_period_s: + type: integer + group_drop_logs: + type: boolean + group_key: + type: string + group_reset_rate_s: + type: integer + group_warning_delay_s: + type: integer + type: object + useragent: + properties: + delete_key: + type: boolean + flatten: + type: boolean + key_name: + type: string + out_key: + type: string + type: object + type: object + type: array + flowLabel: + type: string + globalOutputRefs: + items: + type: string + type: array + includeLabelInRouter: + type: boolean + loggingRef: + type: string + match: + items: + properties: + exclude: + properties: + container_names: + items: + type: string + type: array + hosts: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + namespace_labels: + additionalProperties: + type: string + type: object + namespaces: + items: + type: string + type: array + type: object + select: + properties: + container_names: + items: + type: string + type: array + hosts: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + namespace_labels: + additionalProperties: + type: string + type: object + namespaces: + items: + type: string + type: array + type: object + type: object + type: array + outputRefs: + items: + type: string + type: array + selectors: + additionalProperties: + type: string + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Is the flow active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + filters: + items: + properties: + concat: + properties: + continuous_line_regexp: + type: string + flush_interval: + type: integer + keep_partial_key: + type: boolean + keep_partial_metadata: + type: string + key: + type: string + multiline_end_regexp: + type: string + multiline_start_regexp: + type: string + n_lines: + type: integer + partial_cri_logtag_key: + type: string + partial_cri_stream_key: + type: string + partial_key: + type: string + partial_metadata_format: + type: string + partial_value: + type: string + separator: + type: string + stream_identity_key: + type: string + timeout_label: + type: string + use_first_timestamp: + type: boolean + use_partial_cri_logtag: + type: boolean + use_partial_metadata: + type: string + type: object + dedot: + properties: + de_dot_nested: + type: boolean + de_dot_separator: + type: string + type: object + detectExceptions: + properties: + force_line_breaks: + type: boolean + languages: + items: + type: string + type: array + match_tag: + type: string + max_bytes: + type: integer + max_lines: + type: integer + message: + type: string + multiline_flush_interval: + type: string + remove_tag_prefix: + type: string + stream: + type: string + type: object + elasticsearch_genid: + properties: + hash_id_key: + type: string + hash_type: + type: string + include_tag_in_seed: + type: boolean + include_time_in_seed: + type: boolean + record_keys: + type: string + separator: + type: string + use_entire_record: + type: boolean + use_record_as_seed: + type: boolean + type: object + enhanceK8s: + properties: + api_groups: + items: + type: string + type: array + bearer_token_file: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cache_refresh: + type: integer + cache_refresh_variation: + type: integer + cache_size: + type: integer + cache_ttl: + type: integer + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + core_api_versions: + items: + type: string + type: array + data_type: + type: string + in_namespace_path: + items: + type: string + type: array + in_pod_path: + items: + type: string + type: array + kubernetes_url: + type: string + secret_dir: + type: string + ssl_partial_chain: + type: boolean + verify_ssl: + type: boolean + type: object + geoip: + properties: + backend_library: + type: string + geoip_database: + type: string + geoip_lookup_keys: + type: string + geoip2_database: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + skip_adding_null_record: + type: boolean + type: object + grep: + properties: + and: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + or: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + kube_events_timestamp: + properties: + mapped_time_key: + type: string + timestamp_fields: + items: + type: string + type: array + type: object + parser: + properties: + emit_invalid_record_to_error: + type: boolean + hash_value_field: + type: string + inject_key_prefix: + type: string + key_name: + type: string + parse: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + parsers: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + remove_key_name_field: + type: boolean + replace_invalid_sequence: + type: boolean + reserve_data: + type: boolean + reserve_time: + type: boolean + type: object + prometheus: + properties: + labels: + additionalProperties: + type: string + type: object + metrics: + items: + properties: + buckets: + type: string + desc: + type: string + key: + type: string + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: + type: string + required: + - desc + - name + - type + type: object + type: array + type: object + record_modifier: + properties: + char_encoding: + type: string + prepare_value: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + replaces: + items: + properties: + expression: + type: string + key: + type: string + replace: + type: string + required: + - expression + - key + - replace + type: object + type: array + whitelist_keys: + type: string + type: object + record_transformer: + properties: + auto_typecast: + type: boolean + enable_ruby: + type: boolean + keep_keys: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + renew_record: + type: boolean + renew_time_key: + type: string + type: object + stdout: + properties: + output_type: + type: string + type: object + sumologic: + properties: + collector_key_name: + type: string + collector_value: + type: string + exclude_container_regex: + type: string + exclude_facility_regex: + type: string + exclude_host_regex: + type: string + exclude_namespace_regex: + type: string + exclude_pod_regex: + type: string + exclude_priority_regex: + type: string + exclude_unit_regex: + type: string + log_format: + type: string + source_category: + type: string + source_category_key_name: + type: string + source_category_prefix: + type: string + source_category_replace_dash: + type: string + source_host: + type: string + source_host_key_name: + type: string + source_name: + type: string + source_name_key_name: + type: string + tracing_annotation_prefix: + type: string + tracing_container_name: + type: string + tracing_format: + type: boolean + tracing_host: + type: string + tracing_label_prefix: + type: string + tracing_namespace: + type: string + tracing_pod: + type: string + tracing_pod_id: + type: string + type: object + tag_normaliser: + properties: + format: + type: string + match_tag: + type: string + type: object + throttle: + properties: + group_bucket_limit: + type: integer + group_bucket_period_s: + type: integer + group_drop_logs: + type: boolean + group_key: + type: string + group_reset_rate_s: + type: integer + group_warning_delay_s: + type: integer + type: object + useragent: + properties: + delete_key: + type: boolean + flatten: + type: boolean + key_name: + type: string + out_key: + type: string + type: object + type: object + type: array + flowLabel: + type: string + globalOutputRefs: + items: + type: string + type: array + includeLabelInRouter: + type: boolean + loggingRef: + type: string + match: + items: + properties: + exclude: + properties: + container_names: + items: + type: string + type: array + hosts: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + namespace_labels: + additionalProperties: + type: string + type: object + namespaces: + items: + type: string + type: array + type: object + select: + properties: + container_names: + items: + type: string + type: array + hosts: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + namespace_labels: + additionalProperties: + type: string + type: object + namespaces: + items: + type: string + type: array + type: object + type: object + type: array + outputRefs: + items: + type: string + type: array + selectors: + additionalProperties: + type: string + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_clusteroutputs.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_clusteroutputs.yaml new file mode 100644 index 0000000000..4a5f05e03b --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_clusteroutputs.yaml @@ -0,0 +1,14812 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: clusteroutputs.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: ClusterOutput + listKind: ClusterOutputList + plural: clusteroutputs + singular: clusteroutput + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the output active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + awsElasticsearch: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + content_type: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_ilm_name: + type: string + data_stream_ilm_policy: + type: string + data_stream_ilm_policy_overwrite: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_elasticsearch_version: + type: string + deflector_alias: + type: string + enable_ilm: + type: boolean + endpoint: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_arn: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_session_name: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_web_identity_token_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ecs_container_credentials_relative_uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + region: + type: string + secret_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + sts_credentials_region: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + type: object + exception_backup: + type: boolean + fail_on_detecting_es_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + flush_interval: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + host: + type: string + hosts: + type: string + http_backend: + type: string + id_key: + type: string + ignore_exceptions: + type: string + ilm_policy: + type: string + ilm_policy_id: + type: string + ilm_policy_overwrite: + type: boolean + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_prefix: + type: string + log_es_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_es_version: + type: string + max_retry_putting_template: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys: + type: string + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + rollover_index: + type: boolean + routing_key: + type: string + scheme: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_max_version: + type: string + ssl_min_version: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_key: + type: string + target_type_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + type_name: + type: string + unrecoverable_error_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_es_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + azurestorage: + properties: + auto_create_container: + type: boolean + azure_cloud: + type: string + azure_container: + type: string + azure_imds_api_version: + type: string + azure_object_key_format: + type: string + azure_storage_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + azure_storage_account: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + azure_storage_sas_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + type: string + path: + type: string + slow_flush_log_threshold: + type: string + required: + - azure_container + - azure_storage_account + type: object + cloudwatch: + properties: + auto_create_stream: + type: boolean + aws_instance_profile_credentials_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sts_role_arn: + type: string + aws_sts_session_name: + type: string + aws_use_sts: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + concurrency: + type: integer + endpoint: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + http_proxy: + type: string + include_time_key: + type: boolean + json_handler: + type: string + localtime: + type: boolean + log_group_aws_tags: + type: string + log_group_aws_tags_key: + type: string + log_group_name: + type: string + log_group_name_key: + type: string + log_rejected_request: + type: string + log_stream_name: + type: string + log_stream_name_key: + type: string + max_events_per_batch: + type: integer + max_message_length: + type: integer + message_keys: + type: string + put_log_events_disable_retry_limit: + type: boolean + put_log_events_retry_limit: + type: integer + put_log_events_retry_wait: + type: string + region: + type: string + remove_log_group_aws_tags_key: + type: string + remove_log_group_name_key: + type: string + remove_log_stream_name_key: + type: string + remove_retention_in_days: + type: string + retention_in_days: + type: string + retention_in_days_key: + type: string + slow_flush_log_threshold: + type: string + use_tag_as_group: + type: boolean + use_tag_as_stream: + type: boolean + required: + - region + type: object + datadog: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compression_level: + type: string + dd_hostname: + type: string + dd_source: + type: string + dd_sourcecategory: + type: string + dd_tags: + type: string + host: + type: string + include_tag_key: + type: boolean + max_backoff: + type: string + max_retries: + type: string + no_ssl_validation: + type: boolean + port: + type: string + service: + type: string + slow_flush_log_threshold: + type: string + ssl_port: + type: string + tag_key: + type: string + timestamp_key: + type: string + use_compression: + type: boolean + use_http: + type: boolean + use_json: + type: boolean + use_ssl: + type: boolean + required: + - api_key + type: object + elasticsearch: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + content_type: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_ilm_name: + type: string + data_stream_ilm_policy: + type: string + data_stream_ilm_policy_overwrite: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_elasticsearch_version: + type: string + deflector_alias: + type: string + enable_ilm: + type: boolean + exception_backup: + type: boolean + fail_on_detecting_es_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + hosts: + type: string + http_backend: + type: string + id_key: + type: string + ignore_exceptions: + type: string + ilm_policy: + type: string + ilm_policy_id: + type: string + ilm_policy_overwrite: + type: boolean + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_prefix: + type: string + log_es_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_es_version: + type: string + max_retry_putting_template: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys: + type: string + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + rollover_index: + type: boolean + routing_key: + type: string + scheme: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_max_version: + type: string + ssl_min_version: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_key: + type: string + target_type_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + type_name: + type: string + unrecoverable_error_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_es_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + enabledNamespaces: + items: + type: string + type: array + file: + properties: + add_path_suffix: + type: boolean + append: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compress: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + path: + type: string + path_suffix: + type: string + recompress: + type: boolean + slow_flush_log_threshold: + type: string + symlink_path: + type: boolean + required: + - path + type: object + forward: + properties: + ack_response_timeout: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + connect_timeout: + type: integer + dns_round_robin: + type: boolean + expire_dns_cache: + type: integer + hard_timeout: + type: integer + heartbeat_interval: + type: integer + heartbeat_type: + type: string + ignore_network_errors_at_startup: + type: boolean + keepalive: + type: boolean + keepalive_timeout: + type: integer + phi_failure_detector: + type: boolean + phi_threshold: + type: integer + recover_wait: + type: integer + require_ack_response: + type: boolean + security: + properties: + allow_anonymous_source: + type: boolean + self_hostname: + type: string + shared_key: + type: string + user_auth: + type: boolean + required: + - self_hostname + - shared_key + type: object + send_timeout: + type: integer + servers: + items: + properties: + host: + type: string + name: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + type: integer + shared_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + standby: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + weight: + type: integer + required: + - host + type: object + type: array + slow_flush_log_threshold: + type: string + time_as_integer: + type: boolean + tls_allow_self_signed_cert: + type: boolean + tls_cert_logical_store_name: + type: string + tls_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_cert_thumbprint: + type: string + tls_cert_use_enterprise_store: + type: boolean + tls_ciphers: + type: string + tls_client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_client_private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_client_private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_insecure_mode: + type: boolean + tls_verify_hostname: + type: boolean + tls_version: + type: string + transport: + type: string + verify_connection_at_startup: + type: boolean + required: + - servers + type: object + gcs: + properties: + acl: + type: string + auto_create_bucket: + type: boolean + bucket: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_retries: + type: integer + client_timeout: + type: integer + credentials_json: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + encryption_key: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hex_random_length: + type: integer + keyfile: + type: string + object_key_format: + type: string + object_metadata: + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + overwrite: + type: boolean + path: + type: string + project: + type: string + slow_flush_log_threshold: + type: string + storage_class: + type: string + store_as: + type: string + transcoding: + type: boolean + required: + - bucket + - project + type: object + gelf: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + host: + type: string + port: + type: integer + protocol: + type: string + tls: + type: boolean + tls_options: + additionalProperties: + type: string + type: object + required: + - host + - port + type: object + http: + properties: + auth: + properties: + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - password + - username + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + content_type: + type: string + endpoint: + type: string + error_response_as_unrecoverable: + type: boolean + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + headers: + additionalProperties: + type: string + type: object + http_method: + type: string + json_array: + type: boolean + open_timeout: + type: integer + proxy: + type: string + read_timeout: + type: integer + retryable_response_codes: + items: + type: integer + type: array + slow_flush_log_threshold: + type: string + ssl_timeout: + type: integer + tls_ca_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_ciphers: + type: string + tls_client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_verify_mode: + type: string + tls_version: + type: string + required: + - endpoint + type: object + kafka: + properties: + ack_timeout: + type: integer + brokers: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_id: + type: string + compression_codec: + type: string + default_message_key: + type: string + default_partition_key: + type: string + default_topic: + type: string + discard_kafka_delivery_failed: + type: boolean + exclude_partion_key: + type: boolean + exclude_topic_key: + type: boolean + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + get_kafka_client_log: + type: boolean + headers: + additionalProperties: + type: string + type: object + headers_from_record: + additionalProperties: + type: string + type: object + idempotent: + type: boolean + kafka_agg_max_bytes: + type: integer + kafka_agg_max_messages: + type: integer + keytab: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + max_send_retries: + type: integer + message_key_key: + type: string + partition_key: + type: string + partition_key_key: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + principal: + type: string + required_acks: + type: integer + sasl_over_ssl: + type: boolean + scram_mechanism: + type: string + slow_flush_log_threshold: + type: string + ssl_ca_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_ca_certs_from_system: + type: boolean + ssl_client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_client_cert_chain: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_client_cert_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_verify_hostname: + type: boolean + topic_key: + type: string + use_default_for_unknown_topic: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - brokers + - format + type: object + kinesisFirehose: + properties: + append_new_line: + type: boolean + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + aws_iam_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_ses_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch_request_max_count: + type: integer + batch_request_max_size: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + delivery_stream_name: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + process_credentials: + properties: + process: + type: string + required: + - process + type: object + region: + type: string + reset_backoff_if_success: + type: boolean + retries_on_batch_request: + type: integer + slow_flush_log_threshold: + type: string + required: + - delivery_stream_name + type: object + kinesisStream: + properties: + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + aws_iam_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_ses_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch_request_max_count: + type: integer + batch_request_max_size: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + partition_key: + type: string + process_credentials: + properties: + process: + type: string + required: + - process + type: object + region: + type: string + reset_backoff_if_success: + type: boolean + retries_on_batch_request: + type: integer + slow_flush_log_threshold: + type: string + stream_name: + type: string + required: + - stream_name + type: object + logdna: + properties: + api_key: + type: string + app: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + hostname: + type: string + ingester_domain: + type: string + ingester_endpoint: + type: string + request_timeout: + type: string + slow_flush_log_threshold: + type: string + tags: + type: string + required: + - api_key + - hostname + type: object + loggingRef: + type: string + logz: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_limit: + type: integer + bulk_limit_warning_limit: + type: integer + endpoint: + properties: + port: + type: integer + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + type: object + gzip: + type: boolean + http_idle_timeout: + type: integer + output_include_tags: + type: boolean + output_include_time: + type: boolean + retry_count: + type: integer + retry_sleep: + type: integer + slow_flush_log_threshold: + type: string + required: + - endpoint + type: object + loki: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + configure_kubernetes_labels: + type: boolean + drop_single_key: + type: boolean + extra_labels: + additionalProperties: + type: string + type: object + extract_kubernetes_labels: + type: boolean + include_thread_label: + type: boolean + insecure_tls: + type: boolean + key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + labels: + additionalProperties: + type: string + type: object + line_format: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + remove_keys: + items: + type: string + type: array + slow_flush_log_threshold: + type: string + tenant: + type: string + url: + type: string + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + mattermost: + properties: + ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + channel_id: + type: string + enable_tls: + type: boolean + message: + type: string + message_color: + type: string + message_title: + type: string + webhook_url: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - webhook_url + type: object + newrelic: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + base_uri: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + license_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + nullout: + type: object + opensearch: + properties: + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + catch_transport_exception_on_retry: + type: boolean + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_opensearch_version: + type: integer + emit_error_for_missing_id: + type: boolean + emit_error_label_event: + type: boolean + endpoint: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_arn: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_session_name: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_web_identity_token_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ecs_container_credentials_relative_uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + region: + type: string + secret_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + sts_credentials_region: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + required: + - url + type: object + exception_backup: + type: boolean + fail_on_detecting_os_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + hosts: + type: string + http_backend: + type: string + http_backend_excon_nonblock: + type: boolean + id_key: + type: string + ignore_exceptions: + type: string + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_separator: + type: string + log_os_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_os_version: + type: integer + max_retry_putting_template: + type: string + parent_key: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + routing_key: + type: string + scheme: + type: string + selector_class_name: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_affinity: + type: boolean + target_index_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_exclude_timestamp: + type: boolean + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + truncate_caches_interval: + type: string + unrecoverable_error_types: + type: string + unrecoverable_record_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_os_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + oss: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + access_key_secret: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + auto_create_bucket: + type: boolean + bucket: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + check_bucket: + type: boolean + check_object: + type: boolean + download_crc_enable: + type: boolean + endpoint: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hex_random_length: + type: integer + index_format: + type: string + key_format: + type: string + open_timeout: + type: integer + oss_sdk_log_dir: + type: string + overwrite: + type: boolean + path: + type: string + read_timeout: + type: integer + slow_flush_log_threshold: + type: string + store_as: + type: string + upload_crc_enable: + type: boolean + warn_for_delay: + type: string + required: + - access_key_id + - access_key_secret + - bucket + - endpoint + type: object + protected: + type: boolean + redis: + properties: + allow_duplicate_key: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + db_number: + type: integer + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + host: + type: string + insert_key_prefix: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + type: integer + slow_flush_log_threshold: + type: string + strftime_format: + type: string + ttl: + type: integer + type: object + relabel: + properties: + label: + type: string + required: + - label + type: object + s3: + properties: + acl: + type: string + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + auto_create_bucket: + type: string + aws_iam_retries: + type: string + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + check_apikey_on_start: + type: string + check_bucket: + type: string + check_object: + type: string + clustername: + type: string + compress: + properties: + parquet_compression_codec: + type: string + parquet_page_size: + type: string + parquet_row_group_size: + type: string + record_type: + type: string + schema_file: + type: string + schema_type: + type: string + type: object + compute_checksums: + type: string + enable_transfer_acceleration: + type: string + force_path_style: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + grant_full_control: + type: string + grant_read: + type: string + grant_read_acp: + type: string + grant_write_acp: + type: string + hex_random_length: + type: string + index_format: + type: string + instance_profile_credentials: + properties: + http_open_timeout: + type: string + http_read_timeout: + type: string + ip_address: + type: string + port: + type: string + retries: + type: string + type: object + oneeye_format: + type: boolean + overwrite: + type: string + path: + type: string + proxy_uri: + type: string + s3_bucket: + type: string + s3_endpoint: + type: string + s3_metadata: + type: string + s3_object_key_format: + type: string + s3_region: + type: string + shared_credentials: + properties: + path: + type: string + profile_name: + type: string + type: object + signature_version: + type: string + slow_flush_log_threshold: + type: string + sse_customer_algorithm: + type: string + sse_customer_key: + type: string + sse_customer_key_md5: + type: string + ssekms_key_id: + type: string + ssl_verify_peer: + type: string + storage_class: + type: string + store_as: + type: string + use_bundled_cert: + type: string + use_server_side_encryption: + type: string + warn_for_delay: + type: string + required: + - s3_bucket + type: object + splunkHec: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + coerce_to_utf8: + type: boolean + data_type: + type: string + fields: + additionalProperties: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hec_host: + type: string + hec_port: + type: integer + hec_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + host: + type: string + host_key: + type: string + idle_timeout: + type: integer + index: + type: string + index_key: + type: string + insecure_ssl: + type: boolean + keep_keys: + type: boolean + metric_name_key: + type: string + metric_value_key: + type: string + metrics_from_event: + type: boolean + non_utf8_replacement_string: + type: string + open_timeout: + type: integer + protocol: + type: string + read_timeout: + type: integer + slow_flush_log_threshold: + type: string + source: + type: string + source_key: + type: string + sourcetype: + type: string + sourcetype_key: + type: string + ssl_ciphers: + type: string + required: + - hec_host + - hec_token + type: object + sqs: + properties: + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + create_queue: + type: boolean + delay_seconds: + type: integer + include_tag: + type: boolean + message_group_id: + type: string + queue_name: + type: string + region: + type: string + slow_flush_log_threshold: + type: string + sqs_url: + type: string + tag_property_name: + type: string + type: object + sumologic: + properties: + add_timestamp: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compress: + type: boolean + compress_encoding: + type: string + custom_dimensions: + type: string + custom_fields: + items: + type: string + type: array + data_type: + type: string + delimiter: + type: string + disable_cookies: + type: boolean + endpoint: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + log_format: + type: string + log_key: + type: string + metric_data_format: + type: string + open_timeout: + type: integer + proxy_uri: + type: string + slow_flush_log_threshold: + type: string + source_category: + type: string + source_host: + type: string + source_name: + type: string + source_name_key: + type: string + sumo_client: + type: string + timestamp_key: + type: string + verify_ssl: + type: boolean + required: + - endpoint + - source_name + type: object + syslog: + properties: + allow_self_signed_cert: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + enable_system_cert_store: + type: boolean + format: + properties: + app_name_field: + type: string + hostname_field: + type: string + log_field: + type: string + message_id_field: + type: string + proc_id_field: + type: string + rfc6587_message_size: + type: boolean + structured_data_field: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + fqdn: + type: string + host: + type: string + insecure: + type: boolean + port: + type: integer + private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + slow_flush_log_threshold: + type: string + transport: + type: string + trusted_ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + verify_fqdn: + type: boolean + version: + type: string + required: + - host + type: object + vmwareLogInsight: + properties: + agent_id: + type: string + authentication: + enum: + - nil + - basic + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + config_param: + additionalProperties: + type: string + type: object + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + http_conn_debug: + type: boolean + http_method: + enum: + - post + type: string + log_text_keys: + items: + type: string + type: array + max_batch_size: + type: integer + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + port: + type: integer + raise_on_error: + type: boolean + rate_limit_msec: + type: integer + request_retries: + type: integer + request_timeout: + type: integer + scheme: + enum: + - http + - https + type: string + serializer: + enum: + - json + type: string + shorten_keys: + additionalProperties: + type: string + type: object + ssl_verify: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + vmwareLogIntelligence: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + endpoint_url: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + headers: + properties: + authorization: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + content_type: + type: string + structure: + type: string + required: + - authorization + - content_type + - structure + type: object + http_compress: + type: boolean + verify_ssl: + type: boolean + required: + - endpoint_url + - headers + - verify_ssl + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Is the output active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + awsElasticsearch: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + content_type: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_ilm_name: + type: string + data_stream_ilm_policy: + type: string + data_stream_ilm_policy_overwrite: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_elasticsearch_version: + type: string + deflector_alias: + type: string + enable_ilm: + type: boolean + endpoint: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_arn: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_session_name: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_web_identity_token_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ecs_container_credentials_relative_uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + region: + type: string + secret_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + sts_credentials_region: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + type: object + exception_backup: + type: boolean + fail_on_detecting_es_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + flush_interval: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + host: + type: string + hosts: + type: string + http_backend: + type: string + id_key: + type: string + ignore_exceptions: + type: string + ilm_policy: + type: string + ilm_policy_id: + type: string + ilm_policy_overwrite: + type: boolean + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_prefix: + type: string + log_es_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_es_version: + type: string + max_retry_putting_template: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys: + type: string + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + rollover_index: + type: boolean + routing_key: + type: string + scheme: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_max_version: + type: string + ssl_min_version: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_key: + type: string + target_type_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + type_name: + type: string + unrecoverable_error_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_es_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + azurestorage: + properties: + auto_create_container: + type: boolean + azure_cloud: + type: string + azure_container: + type: string + azure_imds_api_version: + type: string + azure_object_key_format: + type: string + azure_storage_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + azure_storage_account: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + azure_storage_sas_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + type: string + path: + type: string + slow_flush_log_threshold: + type: string + required: + - azure_container + - azure_storage_account + type: object + cloudwatch: + properties: + auto_create_stream: + type: boolean + aws_instance_profile_credentials_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sts_role_arn: + type: string + aws_sts_session_name: + type: string + aws_use_sts: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + concurrency: + type: integer + endpoint: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + http_proxy: + type: string + include_time_key: + type: boolean + json_handler: + type: string + localtime: + type: boolean + log_group_aws_tags: + type: string + log_group_aws_tags_key: + type: string + log_group_name: + type: string + log_group_name_key: + type: string + log_rejected_request: + type: string + log_stream_name: + type: string + log_stream_name_key: + type: string + max_events_per_batch: + type: integer + max_message_length: + type: integer + message_keys: + type: string + put_log_events_disable_retry_limit: + type: boolean + put_log_events_retry_limit: + type: integer + put_log_events_retry_wait: + type: string + region: + type: string + remove_log_group_aws_tags_key: + type: string + remove_log_group_name_key: + type: string + remove_log_stream_name_key: + type: string + remove_retention_in_days: + type: string + retention_in_days: + type: string + retention_in_days_key: + type: string + slow_flush_log_threshold: + type: string + use_tag_as_group: + type: boolean + use_tag_as_stream: + type: boolean + required: + - region + type: object + datadog: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compression_level: + type: string + dd_hostname: + type: string + dd_source: + type: string + dd_sourcecategory: + type: string + dd_tags: + type: string + host: + type: string + include_tag_key: + type: boolean + max_backoff: + type: string + max_retries: + type: string + no_ssl_validation: + type: boolean + port: + type: string + service: + type: string + slow_flush_log_threshold: + type: string + ssl_port: + type: string + tag_key: + type: string + timestamp_key: + type: string + use_compression: + type: boolean + use_http: + type: boolean + use_json: + type: boolean + use_ssl: + type: boolean + required: + - api_key + type: object + elasticsearch: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + content_type: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_ilm_name: + type: string + data_stream_ilm_policy: + type: string + data_stream_ilm_policy_overwrite: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_elasticsearch_version: + type: string + deflector_alias: + type: string + enable_ilm: + type: boolean + exception_backup: + type: boolean + fail_on_detecting_es_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + hosts: + type: string + http_backend: + type: string + id_key: + type: string + ignore_exceptions: + type: string + ilm_policy: + type: string + ilm_policy_id: + type: string + ilm_policy_overwrite: + type: boolean + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_prefix: + type: string + log_es_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_es_version: + type: string + max_retry_putting_template: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys: + type: string + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + rollover_index: + type: boolean + routing_key: + type: string + scheme: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_max_version: + type: string + ssl_min_version: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_key: + type: string + target_type_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + type_name: + type: string + unrecoverable_error_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_es_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + enabledNamespaces: + items: + type: string + type: array + file: + properties: + add_path_suffix: + type: boolean + append: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compress: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + path: + type: string + path_suffix: + type: string + recompress: + type: boolean + slow_flush_log_threshold: + type: string + symlink_path: + type: boolean + required: + - path + type: object + forward: + properties: + ack_response_timeout: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + connect_timeout: + type: integer + dns_round_robin: + type: boolean + expire_dns_cache: + type: integer + hard_timeout: + type: integer + heartbeat_interval: + type: integer + heartbeat_type: + type: string + ignore_network_errors_at_startup: + type: boolean + keepalive: + type: boolean + keepalive_timeout: + type: integer + phi_failure_detector: + type: boolean + phi_threshold: + type: integer + recover_wait: + type: integer + require_ack_response: + type: boolean + security: + properties: + allow_anonymous_source: + type: boolean + self_hostname: + type: string + shared_key: + type: string + user_auth: + type: boolean + required: + - self_hostname + - shared_key + type: object + send_timeout: + type: integer + servers: + items: + properties: + host: + type: string + name: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + type: integer + shared_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + standby: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + weight: + type: integer + required: + - host + type: object + type: array + slow_flush_log_threshold: + type: string + time_as_integer: + type: boolean + tls_allow_self_signed_cert: + type: boolean + tls_cert_logical_store_name: + type: string + tls_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_cert_thumbprint: + type: string + tls_cert_use_enterprise_store: + type: boolean + tls_ciphers: + type: string + tls_client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_client_private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_client_private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_insecure_mode: + type: boolean + tls_verify_hostname: + type: boolean + tls_version: + type: string + transport: + type: string + verify_connection_at_startup: + type: boolean + required: + - servers + type: object + gcs: + properties: + acl: + type: string + auto_create_bucket: + type: boolean + bucket: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_retries: + type: integer + client_timeout: + type: integer + credentials_json: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + encryption_key: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hex_random_length: + type: integer + keyfile: + type: string + object_key_format: + type: string + object_metadata: + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + overwrite: + type: boolean + path: + type: string + project: + type: string + slow_flush_log_threshold: + type: string + storage_class: + type: string + store_as: + type: string + transcoding: + type: boolean + required: + - bucket + - project + type: object + gelf: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + host: + type: string + port: + type: integer + protocol: + type: string + tls: + type: boolean + tls_options: + additionalProperties: + type: string + type: object + required: + - host + - port + type: object + http: + properties: + auth: + properties: + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - password + - username + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + content_type: + type: string + endpoint: + type: string + error_response_as_unrecoverable: + type: boolean + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + headers: + additionalProperties: + type: string + type: object + http_method: + type: string + json_array: + type: boolean + open_timeout: + type: integer + proxy: + type: string + read_timeout: + type: integer + retryable_response_codes: + items: + type: integer + type: array + slow_flush_log_threshold: + type: string + ssl_timeout: + type: integer + tls_ca_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_ciphers: + type: string + tls_client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_verify_mode: + type: string + tls_version: + type: string + required: + - endpoint + type: object + kafka: + properties: + ack_timeout: + type: integer + brokers: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_id: + type: string + compression_codec: + type: string + default_message_key: + type: string + default_partition_key: + type: string + default_topic: + type: string + discard_kafka_delivery_failed: + type: boolean + exclude_partion_key: + type: boolean + exclude_topic_key: + type: boolean + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + get_kafka_client_log: + type: boolean + headers: + additionalProperties: + type: string + type: object + headers_from_record: + additionalProperties: + type: string + type: object + idempotent: + type: boolean + kafka_agg_max_bytes: + type: integer + kafka_agg_max_messages: + type: integer + keytab: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + max_send_retries: + type: integer + message_key_key: + type: string + partition_key: + type: string + partition_key_key: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + principal: + type: string + required_acks: + type: integer + sasl_over_ssl: + type: boolean + scram_mechanism: + type: string + slow_flush_log_threshold: + type: string + ssl_ca_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_ca_certs_from_system: + type: boolean + ssl_client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_client_cert_chain: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_client_cert_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_verify_hostname: + type: boolean + topic_key: + type: string + use_default_for_unknown_topic: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - brokers + - format + type: object + kinesisFirehose: + properties: + append_new_line: + type: boolean + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + aws_iam_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_ses_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch_request_max_count: + type: integer + batch_request_max_size: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + delivery_stream_name: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + process_credentials: + properties: + process: + type: string + required: + - process + type: object + region: + type: string + reset_backoff_if_success: + type: boolean + retries_on_batch_request: + type: integer + slow_flush_log_threshold: + type: string + required: + - delivery_stream_name + type: object + kinesisStream: + properties: + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + aws_iam_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_ses_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch_request_max_count: + type: integer + batch_request_max_size: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + partition_key: + type: string + process_credentials: + properties: + process: + type: string + required: + - process + type: object + region: + type: string + reset_backoff_if_success: + type: boolean + retries_on_batch_request: + type: integer + slow_flush_log_threshold: + type: string + stream_name: + type: string + required: + - stream_name + type: object + logdna: + properties: + api_key: + type: string + app: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + hostname: + type: string + ingester_domain: + type: string + ingester_endpoint: + type: string + request_timeout: + type: string + slow_flush_log_threshold: + type: string + tags: + type: string + required: + - api_key + - hostname + type: object + loggingRef: + type: string + logz: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_limit: + type: integer + bulk_limit_warning_limit: + type: integer + endpoint: + properties: + port: + type: integer + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + type: object + gzip: + type: boolean + http_idle_timeout: + type: integer + output_include_tags: + type: boolean + output_include_time: + type: boolean + retry_count: + type: integer + retry_sleep: + type: integer + slow_flush_log_threshold: + type: string + required: + - endpoint + type: object + loki: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + configure_kubernetes_labels: + type: boolean + drop_single_key: + type: boolean + extra_labels: + additionalProperties: + type: string + type: object + extract_kubernetes_labels: + type: boolean + include_thread_label: + type: boolean + insecure_tls: + type: boolean + key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + labels: + additionalProperties: + type: string + type: object + line_format: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + remove_keys: + items: + type: string + type: array + slow_flush_log_threshold: + type: string + tenant: + type: string + url: + type: string + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + mattermost: + properties: + ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + channel_id: + type: string + enable_tls: + type: boolean + message: + type: string + message_color: + type: string + message_title: + type: string + webhook_url: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - webhook_url + type: object + newrelic: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + base_uri: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + license_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + nullout: + type: object + opensearch: + properties: + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + catch_transport_exception_on_retry: + type: boolean + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_opensearch_version: + type: integer + emit_error_for_missing_id: + type: boolean + emit_error_label_event: + type: boolean + endpoint: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_arn: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_session_name: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_web_identity_token_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ecs_container_credentials_relative_uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + region: + type: string + secret_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + sts_credentials_region: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + required: + - url + type: object + exception_backup: + type: boolean + fail_on_detecting_os_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + hosts: + type: string + http_backend: + type: string + http_backend_excon_nonblock: + type: boolean + id_key: + type: string + ignore_exceptions: + type: string + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_separator: + type: string + log_os_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_os_version: + type: integer + max_retry_putting_template: + type: string + parent_key: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + routing_key: + type: string + scheme: + type: string + selector_class_name: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_affinity: + type: boolean + target_index_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_exclude_timestamp: + type: boolean + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + truncate_caches_interval: + type: string + unrecoverable_error_types: + type: string + unrecoverable_record_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_os_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + oss: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + access_key_secret: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + auto_create_bucket: + type: boolean + bucket: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + check_bucket: + type: boolean + check_object: + type: boolean + download_crc_enable: + type: boolean + endpoint: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hex_random_length: + type: integer + index_format: + type: string + key_format: + type: string + open_timeout: + type: integer + oss_sdk_log_dir: + type: string + overwrite: + type: boolean + path: + type: string + read_timeout: + type: integer + slow_flush_log_threshold: + type: string + store_as: + type: string + upload_crc_enable: + type: boolean + warn_for_delay: + type: string + required: + - access_key_id + - access_key_secret + - bucket + - endpoint + type: object + protected: + type: boolean + redis: + properties: + allow_duplicate_key: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + db_number: + type: integer + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + host: + type: string + insert_key_prefix: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + type: integer + slow_flush_log_threshold: + type: string + strftime_format: + type: string + ttl: + type: integer + type: object + relabel: + properties: + label: + type: string + required: + - label + type: object + s3: + properties: + acl: + type: string + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + auto_create_bucket: + type: string + aws_iam_retries: + type: string + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + check_apikey_on_start: + type: string + check_bucket: + type: string + check_object: + type: string + clustername: + type: string + compress: + properties: + parquet_compression_codec: + type: string + parquet_page_size: + type: string + parquet_row_group_size: + type: string + record_type: + type: string + schema_file: + type: string + schema_type: + type: string + type: object + compute_checksums: + type: string + enable_transfer_acceleration: + type: string + force_path_style: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + grant_full_control: + type: string + grant_read: + type: string + grant_read_acp: + type: string + grant_write_acp: + type: string + hex_random_length: + type: string + index_format: + type: string + instance_profile_credentials: + properties: + http_open_timeout: + type: string + http_read_timeout: + type: string + ip_address: + type: string + port: + type: string + retries: + type: string + type: object + oneeye_format: + type: boolean + overwrite: + type: string + path: + type: string + proxy_uri: + type: string + s3_bucket: + type: string + s3_endpoint: + type: string + s3_metadata: + type: string + s3_object_key_format: + type: string + s3_region: + type: string + shared_credentials: + properties: + path: + type: string + profile_name: + type: string + type: object + signature_version: + type: string + slow_flush_log_threshold: + type: string + sse_customer_algorithm: + type: string + sse_customer_key: + type: string + sse_customer_key_md5: + type: string + ssekms_key_id: + type: string + ssl_verify_peer: + type: string + storage_class: + type: string + store_as: + type: string + use_bundled_cert: + type: string + use_server_side_encryption: + type: string + warn_for_delay: + type: string + required: + - s3_bucket + type: object + splunkHec: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + coerce_to_utf8: + type: boolean + data_type: + type: string + fields: + additionalProperties: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hec_host: + type: string + hec_port: + type: integer + hec_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + host: + type: string + host_key: + type: string + idle_timeout: + type: integer + index: + type: string + index_key: + type: string + insecure_ssl: + type: boolean + keep_keys: + type: boolean + metric_name_key: + type: string + metric_value_key: + type: string + metrics_from_event: + type: boolean + non_utf8_replacement_string: + type: string + open_timeout: + type: integer + protocol: + type: string + read_timeout: + type: integer + slow_flush_log_threshold: + type: string + source: + type: string + source_key: + type: string + sourcetype: + type: string + sourcetype_key: + type: string + ssl_ciphers: + type: string + required: + - hec_host + - hec_token + type: object + sqs: + properties: + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + create_queue: + type: boolean + delay_seconds: + type: integer + include_tag: + type: boolean + message_group_id: + type: string + queue_name: + type: string + region: + type: string + slow_flush_log_threshold: + type: string + sqs_url: + type: string + tag_property_name: + type: string + type: object + sumologic: + properties: + add_timestamp: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compress: + type: boolean + compress_encoding: + type: string + custom_dimensions: + type: string + custom_fields: + items: + type: string + type: array + data_type: + type: string + delimiter: + type: string + disable_cookies: + type: boolean + endpoint: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + log_format: + type: string + log_key: + type: string + metric_data_format: + type: string + open_timeout: + type: integer + proxy_uri: + type: string + slow_flush_log_threshold: + type: string + source_category: + type: string + source_host: + type: string + source_name: + type: string + source_name_key: + type: string + sumo_client: + type: string + timestamp_key: + type: string + verify_ssl: + type: boolean + required: + - endpoint + - source_name + type: object + syslog: + properties: + allow_self_signed_cert: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + enable_system_cert_store: + type: boolean + format: + properties: + app_name_field: + type: string + hostname_field: + type: string + log_field: + type: string + message_id_field: + type: string + proc_id_field: + type: string + rfc6587_message_size: + type: boolean + structured_data_field: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + fqdn: + type: string + host: + type: string + insecure: + type: boolean + port: + type: integer + private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + slow_flush_log_threshold: + type: string + transport: + type: string + trusted_ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + verify_fqdn: + type: boolean + version: + type: string + required: + - host + type: object + vmwareLogInsight: + properties: + agent_id: + type: string + authentication: + enum: + - nil + - basic + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + config_param: + additionalProperties: + type: string + type: object + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + http_conn_debug: + type: boolean + http_method: + enum: + - post + type: string + log_text_keys: + items: + type: string + type: array + max_batch_size: + type: integer + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + port: + type: integer + raise_on_error: + type: boolean + rate_limit_msec: + type: integer + request_retries: + type: integer + request_timeout: + type: integer + scheme: + enum: + - http + - https + type: string + serializer: + enum: + - json + type: string + shorten_keys: + additionalProperties: + type: string + type: object + ssl_verify: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + vmwareLogIntelligence: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + endpoint_url: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + headers: + properties: + authorization: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + content_type: + type: string + structure: + type: string + required: + - authorization + - content_type + - structure + type: object + http_compress: + type: boolean + verify_ssl: + type: boolean + required: + - endpoint_url + - headers + - verify_ssl + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_flows.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_flows.yaml new file mode 100644 index 0000000000..2a67723623 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_flows.yaml @@ -0,0 +1,2150 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: flows.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: Flow + listKind: FlowList + plural: flows + singular: flow + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the flow active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + filters: + items: + properties: + concat: + properties: + continuous_line_regexp: + type: string + flush_interval: + type: integer + keep_partial_key: + type: boolean + keep_partial_metadata: + type: string + key: + type: string + multiline_end_regexp: + type: string + multiline_start_regexp: + type: string + n_lines: + type: integer + partial_cri_logtag_key: + type: string + partial_cri_stream_key: + type: string + partial_key: + type: string + partial_metadata_format: + type: string + partial_value: + type: string + separator: + type: string + stream_identity_key: + type: string + timeout_label: + type: string + use_first_timestamp: + type: boolean + use_partial_cri_logtag: + type: boolean + use_partial_metadata: + type: string + type: object + dedot: + properties: + de_dot_nested: + type: boolean + de_dot_separator: + type: string + type: object + detectExceptions: + properties: + force_line_breaks: + type: boolean + languages: + items: + type: string + type: array + match_tag: + type: string + max_bytes: + type: integer + max_lines: + type: integer + message: + type: string + multiline_flush_interval: + type: string + remove_tag_prefix: + type: string + stream: + type: string + type: object + elasticsearch_genid: + properties: + hash_id_key: + type: string + hash_type: + type: string + include_tag_in_seed: + type: boolean + include_time_in_seed: + type: boolean + record_keys: + type: string + separator: + type: string + use_entire_record: + type: boolean + use_record_as_seed: + type: boolean + type: object + enhanceK8s: + properties: + api_groups: + items: + type: string + type: array + bearer_token_file: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cache_refresh: + type: integer + cache_refresh_variation: + type: integer + cache_size: + type: integer + cache_ttl: + type: integer + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + core_api_versions: + items: + type: string + type: array + data_type: + type: string + in_namespace_path: + items: + type: string + type: array + in_pod_path: + items: + type: string + type: array + kubernetes_url: + type: string + secret_dir: + type: string + ssl_partial_chain: + type: boolean + verify_ssl: + type: boolean + type: object + geoip: + properties: + backend_library: + type: string + geoip_database: + type: string + geoip_lookup_keys: + type: string + geoip2_database: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + skip_adding_null_record: + type: boolean + type: object + grep: + properties: + and: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + or: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + kube_events_timestamp: + properties: + mapped_time_key: + type: string + timestamp_fields: + items: + type: string + type: array + type: object + parser: + properties: + emit_invalid_record_to_error: + type: boolean + hash_value_field: + type: string + inject_key_prefix: + type: string + key_name: + type: string + parse: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + parsers: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + remove_key_name_field: + type: boolean + replace_invalid_sequence: + type: boolean + reserve_data: + type: boolean + reserve_time: + type: boolean + type: object + prometheus: + properties: + labels: + additionalProperties: + type: string + type: object + metrics: + items: + properties: + buckets: + type: string + desc: + type: string + key: + type: string + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: + type: string + required: + - desc + - name + - type + type: object + type: array + type: object + record_modifier: + properties: + char_encoding: + type: string + prepare_value: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + replaces: + items: + properties: + expression: + type: string + key: + type: string + replace: + type: string + required: + - expression + - key + - replace + type: object + type: array + whitelist_keys: + type: string + type: object + record_transformer: + properties: + auto_typecast: + type: boolean + enable_ruby: + type: boolean + keep_keys: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + renew_record: + type: boolean + renew_time_key: + type: string + type: object + stdout: + properties: + output_type: + type: string + type: object + sumologic: + properties: + collector_key_name: + type: string + collector_value: + type: string + exclude_container_regex: + type: string + exclude_facility_regex: + type: string + exclude_host_regex: + type: string + exclude_namespace_regex: + type: string + exclude_pod_regex: + type: string + exclude_priority_regex: + type: string + exclude_unit_regex: + type: string + log_format: + type: string + source_category: + type: string + source_category_key_name: + type: string + source_category_prefix: + type: string + source_category_replace_dash: + type: string + source_host: + type: string + source_host_key_name: + type: string + source_name: + type: string + source_name_key_name: + type: string + tracing_annotation_prefix: + type: string + tracing_container_name: + type: string + tracing_format: + type: boolean + tracing_host: + type: string + tracing_label_prefix: + type: string + tracing_namespace: + type: string + tracing_pod: + type: string + tracing_pod_id: + type: string + type: object + tag_normaliser: + properties: + format: + type: string + match_tag: + type: string + type: object + throttle: + properties: + group_bucket_limit: + type: integer + group_bucket_period_s: + type: integer + group_drop_logs: + type: boolean + group_key: + type: string + group_reset_rate_s: + type: integer + group_warning_delay_s: + type: integer + type: object + useragent: + properties: + delete_key: + type: boolean + flatten: + type: boolean + key_name: + type: string + out_key: + type: string + type: object + type: object + type: array + flowLabel: + type: string + globalOutputRefs: + items: + type: string + type: array + includeLabelInRouter: + type: boolean + localOutputRefs: + items: + type: string + type: array + loggingRef: + type: string + match: + items: + properties: + exclude: + properties: + container_names: + items: + type: string + type: array + hosts: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + namespace_labels: + additionalProperties: + type: string + type: object + type: object + select: + properties: + container_names: + items: + type: string + type: array + hosts: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + outputRefs: + items: + type: string + type: array + selectors: + additionalProperties: + type: string + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Is the flow active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + filters: + items: + properties: + concat: + properties: + continuous_line_regexp: + type: string + flush_interval: + type: integer + keep_partial_key: + type: boolean + keep_partial_metadata: + type: string + key: + type: string + multiline_end_regexp: + type: string + multiline_start_regexp: + type: string + n_lines: + type: integer + partial_cri_logtag_key: + type: string + partial_cri_stream_key: + type: string + partial_key: + type: string + partial_metadata_format: + type: string + partial_value: + type: string + separator: + type: string + stream_identity_key: + type: string + timeout_label: + type: string + use_first_timestamp: + type: boolean + use_partial_cri_logtag: + type: boolean + use_partial_metadata: + type: string + type: object + dedot: + properties: + de_dot_nested: + type: boolean + de_dot_separator: + type: string + type: object + detectExceptions: + properties: + force_line_breaks: + type: boolean + languages: + items: + type: string + type: array + match_tag: + type: string + max_bytes: + type: integer + max_lines: + type: integer + message: + type: string + multiline_flush_interval: + type: string + remove_tag_prefix: + type: string + stream: + type: string + type: object + elasticsearch_genid: + properties: + hash_id_key: + type: string + hash_type: + type: string + include_tag_in_seed: + type: boolean + include_time_in_seed: + type: boolean + record_keys: + type: string + separator: + type: string + use_entire_record: + type: boolean + use_record_as_seed: + type: boolean + type: object + enhanceK8s: + properties: + api_groups: + items: + type: string + type: array + bearer_token_file: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cache_refresh: + type: integer + cache_refresh_variation: + type: integer + cache_size: + type: integer + cache_ttl: + type: integer + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + core_api_versions: + items: + type: string + type: array + data_type: + type: string + in_namespace_path: + items: + type: string + type: array + in_pod_path: + items: + type: string + type: array + kubernetes_url: + type: string + secret_dir: + type: string + ssl_partial_chain: + type: boolean + verify_ssl: + type: boolean + type: object + geoip: + properties: + backend_library: + type: string + geoip_database: + type: string + geoip_lookup_keys: + type: string + geoip2_database: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + skip_adding_null_record: + type: boolean + type: object + grep: + properties: + and: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + or: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + kube_events_timestamp: + properties: + mapped_time_key: + type: string + timestamp_fields: + items: + type: string + type: array + type: object + parser: + properties: + emit_invalid_record_to_error: + type: boolean + hash_value_field: + type: string + inject_key_prefix: + type: string + key_name: + type: string + parse: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + parsers: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + remove_key_name_field: + type: boolean + replace_invalid_sequence: + type: boolean + reserve_data: + type: boolean + reserve_time: + type: boolean + type: object + prometheus: + properties: + labels: + additionalProperties: + type: string + type: object + metrics: + items: + properties: + buckets: + type: string + desc: + type: string + key: + type: string + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: + type: string + required: + - desc + - name + - type + type: object + type: array + type: object + record_modifier: + properties: + char_encoding: + type: string + prepare_value: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + replaces: + items: + properties: + expression: + type: string + key: + type: string + replace: + type: string + required: + - expression + - key + - replace + type: object + type: array + whitelist_keys: + type: string + type: object + record_transformer: + properties: + auto_typecast: + type: boolean + enable_ruby: + type: boolean + keep_keys: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + renew_record: + type: boolean + renew_time_key: + type: string + type: object + stdout: + properties: + output_type: + type: string + type: object + sumologic: + properties: + collector_key_name: + type: string + collector_value: + type: string + exclude_container_regex: + type: string + exclude_facility_regex: + type: string + exclude_host_regex: + type: string + exclude_namespace_regex: + type: string + exclude_pod_regex: + type: string + exclude_priority_regex: + type: string + exclude_unit_regex: + type: string + log_format: + type: string + source_category: + type: string + source_category_key_name: + type: string + source_category_prefix: + type: string + source_category_replace_dash: + type: string + source_host: + type: string + source_host_key_name: + type: string + source_name: + type: string + source_name_key_name: + type: string + tracing_annotation_prefix: + type: string + tracing_container_name: + type: string + tracing_format: + type: boolean + tracing_host: + type: string + tracing_label_prefix: + type: string + tracing_namespace: + type: string + tracing_pod: + type: string + tracing_pod_id: + type: string + type: object + tag_normaliser: + properties: + format: + type: string + match_tag: + type: string + type: object + throttle: + properties: + group_bucket_limit: + type: integer + group_bucket_period_s: + type: integer + group_drop_logs: + type: boolean + group_key: + type: string + group_reset_rate_s: + type: integer + group_warning_delay_s: + type: integer + type: object + useragent: + properties: + delete_key: + type: boolean + flatten: + type: boolean + key_name: + type: string + out_key: + type: string + type: object + type: object + type: array + flowLabel: + type: string + globalOutputRefs: + items: + type: string + type: array + includeLabelInRouter: + type: boolean + localOutputRefs: + items: + type: string + type: array + loggingRef: + type: string + match: + items: + properties: + exclude: + properties: + container_names: + items: + type: string + type: array + hosts: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + namespace_labels: + additionalProperties: + type: string + type: object + type: object + select: + properties: + container_names: + items: + type: string + type: array + hosts: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + outputRefs: + items: + type: string + type: array + selectors: + additionalProperties: + type: string + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_fluentbitagents.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_fluentbitagents.yaml new file mode 100644 index 0000000000..d9148dc802 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_fluentbitagents.yaml @@ -0,0 +1,2535 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: fluentbitagents.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: FluentbitAgent + listKind: FluentbitAgentList + plural: fluentbitagents + singular: fluentbitagent + scope: Cluster + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + HostNetwork: + type: boolean + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + bufferStorage: + properties: + storage.backlog.mem_limit: + type: string + storage.checksum: + type: string + storage.delete_irrecoverable_chunks: + type: string + storage.metrics: + type: string + storage.path: + type: string + storage.sync: + type: string + type: object + bufferStorageVolume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + bufferVolumeArgs: + items: + type: string + type: array + bufferVolumeImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + bufferVolumeMetrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + bufferVolumeResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + configHotReload: + properties: + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + coroStackSize: + format: int32 + type: integer + customConfigSecret: + type: string + customParsers: + type: string + daemonsetAnnotations: + additionalProperties: + type: string + type: object + disableKubernetesFilter: + type: boolean + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableUpstream: + type: boolean + envVars: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + extraVolumeMounts: + items: + properties: + destination: + pattern: ^/.+$ + type: string + readOnly: + type: boolean + source: + pattern: ^/.+$ + type: string + required: + - destination + - source + type: object + type: array + filterAws: + properties: + Match: + type: string + account_id: + type: boolean + ami_id: + type: boolean + az: + type: boolean + ec2_instance_id: + type: boolean + ec2_instance_type: + type: boolean + hostname: + type: boolean + imds_version: + type: string + private_ip: + type: boolean + vpc_id: + type: boolean + type: object + filterKubernetes: + properties: + Annotations: + type: string + Buffer_Size: + type: string + Cache_Use_Docker_Id: + type: string + DNS_Retries: + type: string + DNS_Wait_Time: + type: string + Dummy_Meta: + type: string + K8S-Logging.Exclude: + type: string + K8S-Logging.Parser: + type: string + Keep_Log: + type: string + Kube_CA_File: + type: string + Kube_CA_Path: + type: string + Kube_Meta_Cache_TTL: + type: string + Kube_Tag_Prefix: + type: string + Kube_Token_File: + type: string + Kube_Token_TTL: + type: string + Kube_URL: + type: string + Kube_meta_preload_cache_dir: + type: string + Kubelet_Port: + type: string + Labels: + type: string + Match: + type: string + Merge_Log: + type: string + Merge_Log_Key: + type: string + Merge_Log_Trim: + type: string + Merge_Parser: + type: string + Regex_Parser: + type: string + Use_Journal: + type: string + Use_Kubelet: + type: string + kube_meta_namespace_cache_ttl: + type: string + namespace_annotations: + type: string + namespace_labels: + type: string + tls.debug: + type: string + tls.verify: + type: string + type: object + filterModify: + items: + properties: + conditions: + items: + properties: + A_key_matches: + properties: + key: + type: string + type: object + Key_does_not_exist: + properties: + key: + type: string + value: + type: string + type: object + Key_exists: + properties: + key: + type: string + type: object + Key_value_does_not_equal: + properties: + key: + type: string + value: + type: string + type: object + Key_value_does_not_match: + properties: + key: + type: string + value: + type: string + type: object + Key_value_equals: + properties: + key: + type: string + value: + type: string + type: object + Key_value_matches: + properties: + key: + type: string + value: + type: string + type: object + Matching_keys_do_not_have_matching_values: + properties: + key: + type: string + value: + type: string + type: object + Matching_keys_have_matching_values: + properties: + key: + type: string + value: + type: string + type: object + No_key_matches: + properties: + key: + type: string + type: object + type: object + type: array + rules: + items: + properties: + Add: + properties: + key: + type: string + value: + type: string + type: object + Copy: + properties: + key: + type: string + value: + type: string + type: object + Hard_copy: + properties: + key: + type: string + value: + type: string + type: object + Hard_rename: + properties: + key: + type: string + value: + type: string + type: object + Remove: + properties: + key: + type: string + type: object + Remove_regex: + properties: + key: + type: string + type: object + Remove_wildcard: + properties: + key: + type: string + type: object + Rename: + properties: + key: + type: string + value: + type: string + type: object + Set: + properties: + key: + type: string + value: + type: string + type: object + type: object + type: array + type: object + type: array + flush: + format: int32 + type: integer + forwardOptions: + properties: + Require_ack_response: + type: boolean + Retry_Limit: + type: string + Send_options: + type: boolean + Tag: + type: string + Time_as_Integer: + type: boolean + Workers: + type: integer + storage.total_limit_size: + type: string + type: object + grace: + format: int32 + type: integer + healthCheck: + properties: + hcErrorsCount: + type: integer + hcPeriod: + type: integer + hcRetryFailureCount: + type: integer + type: object + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + inputTail: + properties: + Buffer_Chunk_Size: + type: string + Buffer_Max_Size: + type: string + DB: + type: string + DB.journal_mode: + type: string + DB.locking: + type: boolean + DB_Sync: + type: string + Docker_Mode: + type: string + Docker_Mode_Flush: + type: string + Docker_Mode_Parser: + type: string + Exclude_Path: + type: string + Ignore_Older: + type: string + Key: + type: string + Mem_Buf_Limit: + type: string + Multiline: + type: string + Multiline_Flush: + type: string + Parser: + type: string + Parser_Firstline: + type: string + Parser_N: + items: + type: string + type: array + Path: + type: string + Path_Key: + type: string + Read_From_Head: + type: boolean + Refresh_Interval: + type: string + Rotate_Wait: + type: string + Skip_Long_Lines: + type: string + Tag: + type: string + Tag_Regex: + type: string + multiline.parser: + items: + type: string + type: array + storage.type: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + livenessDefaultCheck: + type: boolean + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + logLevel: + type: string + loggingRef: + type: string + metrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + mountPath: + type: string + network: + properties: + connectTimeout: + format: int32 + type: integer + connectTimeoutLogError: + type: boolean + dnsMode: + type: string + dnsPreferIpv4: + type: boolean + dnsResolver: + type: string + keepalive: + type: boolean + keepaliveIdleTimeout: + format: int32 + type: integer + keepaliveMaxRecycle: + format: int32 + type: integer + maxWorkerConnections: + type: integer + sourceAddress: + type: string + type: object + nodeSelector: + additionalProperties: + type: string + type: object + parser: + type: string + podPriorityClassName: + type: string + position_db: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + positiondb: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + security: + properties: + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + podSecurityPolicyCreate: + type: boolean + roleBasedAccessControlCreate: + type: boolean + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + type: object + serviceAccount: + properties: + automountServiceAccountToken: + type: boolean + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + secrets: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + type: object + syslogng_output: + properties: + Retry_Limit: + type: string + Workers: + type: integer + json_date_format: + type: string + json_date_key: + type: string + type: object + targetHost: + type: string + targetPort: + format: int32 + type: integer + tls: + properties: + enabled: + type: boolean + secretName: + type: string + sharedKey: + type: string + required: + - enabled + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + updateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_fluentdconfigs.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_fluentdconfigs.yaml new file mode 100644 index 0000000000..68b148cc33 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_fluentdconfigs.yaml @@ -0,0 +1,3240 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: fluentdconfigs.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: FluentdConfig + listKind: FluentdConfigList + plural: fluentdconfigs + singular: fluentdconfig + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the fluentd configuration active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + bufferStorageVolume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + bufferVolumeArgs: + items: + type: string + type: array + bufferVolumeImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + bufferVolumeMetrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + bufferVolumeResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + compressConfigFile: + type: boolean + configCheck: + properties: + labels: + additionalProperties: + type: string + type: object + strategy: + type: string + timeoutSeconds: + type: integer + type: object + configCheckAnnotations: + additionalProperties: + type: string + type: object + configCheckResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + configReloaderImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + configReloaderResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + disablePvc: + type: boolean + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableMsgpackTimeSupport: + type: boolean + envVars: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + extraArgs: + items: + type: string + type: array + extraVolumes: + items: + properties: + containerName: + type: string + path: + type: string + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeName: + type: string + type: object + type: array + fluentLogDestination: + type: string + fluentOutLogrotate: + properties: + age: + type: string + enabled: + type: boolean + path: + type: string + size: + type: string + required: + - enabled + type: object + fluentdPvcSpec: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + forwardInputConfig: + properties: + add_tag_prefix: + type: string + bind: + type: string + chunk_size_limit: + type: string + chunk_size_warn_limit: + type: string + deny_keepalive: + type: boolean + linger_timeout: + type: integer + port: + type: string + resolve_hostname: + type: boolean + security: + properties: + allow_anonymous_source: + type: boolean + self_hostname: + type: string + shared_key: + type: string + user_auth: + type: boolean + required: + - self_hostname + - shared_key + type: object + send_keepalive_packet: + type: boolean + skip_invalid_event: + type: boolean + source_address_key: + type: string + sourceHostnameKey: + type: string + tag: + type: string + transport: + properties: + ca_cert_path: + type: string + ca_path: + type: string + ca_private_key_passphrase: + type: string + ca_private_key_path: + type: string + cert_path: + type: string + ciphers: + type: string + client_cert_auth: + type: boolean + insecure: + type: boolean + private_key_passphrase: + type: string + private_key_path: + type: string + protocol: + type: string + version: + type: string + type: object + type: object + ignoreRepeatedLogInterval: + type: string + ignoreSameLogInterval: + type: string + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + livenessDefaultCheck: + type: boolean + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + logFormat: + type: string + logLevel: + type: string + metrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pdb: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + unhealthyPodEvictionPolicy: + type: string + type: object + podPriorityClassName: + type: string + port: + format: int32 + type: integer + readinessDefaultCheck: + properties: + bufferFileNumber: + type: boolean + bufferFileNumberMax: + format: int32 + type: integer + bufferFreeSpace: + type: boolean + bufferFreeSpaceThreshold: + format: int32 + type: integer + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + rootDir: + type: string + scaling: + properties: + drain: + properties: + annotations: + additionalProperties: + type: string + type: object + deleteVolume: + type: boolean + enabled: + type: boolean + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + pauseImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + podManagementPolicy: + type: string + replicas: + type: integer + type: object + security: + properties: + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + podSecurityPolicyCreate: + type: boolean + roleBasedAccessControlCreate: + type: boolean + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + type: object + serviceAccount: + properties: + automountServiceAccountToken: + type: boolean + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + secrets: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + type: object + sidecarContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + statefulsetAnnotations: + additionalProperties: + type: string + type: object + tls: + properties: + enabled: + type: boolean + secretName: + type: string + sharedKey: + type: string + required: + - enabled + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + volumeModImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + volumeMountChmod: + type: boolean + workers: + format: int32 + type: integer + type: object + status: + properties: + active: + type: boolean + logging: + type: string + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_loggingroutes.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_loggingroutes.yaml new file mode 100644 index 0000000000..2b465f2d6f --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_loggingroutes.yaml @@ -0,0 +1,106 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: loggingroutes.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: LoggingRoute + listKind: LoggingRouteList + plural: loggingroutes + shortNames: + - lr + singular: loggingroute + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + - description: Number of notices + jsonPath: .status.noticesCount + name: Notices + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + source: + type: string + targets: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - source + - targets + type: object + status: + properties: + notices: + items: + type: string + type: array + noticesCount: + type: integer + problems: + items: + type: string + type: array + problemsCount: + type: integer + tenants: + items: + properties: + name: + type: string + namespaces: + items: + type: string + type: array + required: + - name + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_loggings.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_loggings.yaml new file mode 100644 index 0000000000..46c7f5f6c3 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_loggings.yaml @@ -0,0 +1,20601 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: loggings.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: Logging + listKind: LoggingList + plural: loggings + singular: logging + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + status: + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Logging reference + jsonPath: .spec.loggingRef + name: LoggingRef + type: string + - description: Control namespace + jsonPath: .spec.controlNamespace + name: ControlNamespace + type: string + - description: Watched namespaces + jsonPath: .status.watchNamespaces + name: WatchNamespaces + type: string + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + allowClusterResourcesFromAllNamespaces: + type: boolean + clusterDomain: + type: string + configCheck: + properties: + labels: + additionalProperties: + type: string + type: object + strategy: + type: string + timeoutSeconds: + type: integer + type: object + controlNamespace: + type: string + defaultFlow: + properties: + filters: + items: + properties: + concat: + properties: + continuous_line_regexp: + type: string + flush_interval: + type: integer + keep_partial_key: + type: boolean + keep_partial_metadata: + type: string + key: + type: string + multiline_end_regexp: + type: string + multiline_start_regexp: + type: string + n_lines: + type: integer + partial_cri_logtag_key: + type: string + partial_cri_stream_key: + type: string + partial_key: + type: string + partial_metadata_format: + type: string + partial_value: + type: string + separator: + type: string + stream_identity_key: + type: string + timeout_label: + type: string + use_first_timestamp: + type: boolean + use_partial_cri_logtag: + type: boolean + use_partial_metadata: + type: string + type: object + dedot: + properties: + de_dot_nested: + type: boolean + de_dot_separator: + type: string + type: object + detectExceptions: + properties: + force_line_breaks: + type: boolean + languages: + items: + type: string + type: array + match_tag: + type: string + max_bytes: + type: integer + max_lines: + type: integer + message: + type: string + multiline_flush_interval: + type: string + remove_tag_prefix: + type: string + stream: + type: string + type: object + elasticsearch_genid: + properties: + hash_id_key: + type: string + hash_type: + type: string + include_tag_in_seed: + type: boolean + include_time_in_seed: + type: boolean + record_keys: + type: string + separator: + type: string + use_entire_record: + type: boolean + use_record_as_seed: + type: boolean + type: object + enhanceK8s: + properties: + api_groups: + items: + type: string + type: array + bearer_token_file: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cache_refresh: + type: integer + cache_refresh_variation: + type: integer + cache_size: + type: integer + cache_ttl: + type: integer + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + core_api_versions: + items: + type: string + type: array + data_type: + type: string + in_namespace_path: + items: + type: string + type: array + in_pod_path: + items: + type: string + type: array + kubernetes_url: + type: string + secret_dir: + type: string + ssl_partial_chain: + type: boolean + verify_ssl: + type: boolean + type: object + geoip: + properties: + backend_library: + type: string + geoip_database: + type: string + geoip_lookup_keys: + type: string + geoip2_database: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + skip_adding_null_record: + type: boolean + type: object + grep: + properties: + and: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + or: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + kube_events_timestamp: + properties: + mapped_time_key: + type: string + timestamp_fields: + items: + type: string + type: array + type: object + parser: + properties: + emit_invalid_record_to_error: + type: boolean + hash_value_field: + type: string + inject_key_prefix: + type: string + key_name: + type: string + parse: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + parsers: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + remove_key_name_field: + type: boolean + replace_invalid_sequence: + type: boolean + reserve_data: + type: boolean + reserve_time: + type: boolean + type: object + prometheus: + properties: + labels: + additionalProperties: + type: string + type: object + metrics: + items: + properties: + buckets: + type: string + desc: + type: string + key: + type: string + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: + type: string + required: + - desc + - name + - type + type: object + type: array + type: object + record_modifier: + properties: + char_encoding: + type: string + prepare_value: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + replaces: + items: + properties: + expression: + type: string + key: + type: string + replace: + type: string + required: + - expression + - key + - replace + type: object + type: array + whitelist_keys: + type: string + type: object + record_transformer: + properties: + auto_typecast: + type: boolean + enable_ruby: + type: boolean + keep_keys: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + renew_record: + type: boolean + renew_time_key: + type: string + type: object + stdout: + properties: + output_type: + type: string + type: object + sumologic: + properties: + collector_key_name: + type: string + collector_value: + type: string + exclude_container_regex: + type: string + exclude_facility_regex: + type: string + exclude_host_regex: + type: string + exclude_namespace_regex: + type: string + exclude_pod_regex: + type: string + exclude_priority_regex: + type: string + exclude_unit_regex: + type: string + log_format: + type: string + source_category: + type: string + source_category_key_name: + type: string + source_category_prefix: + type: string + source_category_replace_dash: + type: string + source_host: + type: string + source_host_key_name: + type: string + source_name: + type: string + source_name_key_name: + type: string + tracing_annotation_prefix: + type: string + tracing_container_name: + type: string + tracing_format: + type: boolean + tracing_host: + type: string + tracing_label_prefix: + type: string + tracing_namespace: + type: string + tracing_pod: + type: string + tracing_pod_id: + type: string + type: object + tag_normaliser: + properties: + format: + type: string + match_tag: + type: string + type: object + throttle: + properties: + group_bucket_limit: + type: integer + group_bucket_period_s: + type: integer + group_drop_logs: + type: boolean + group_key: + type: string + group_reset_rate_s: + type: integer + group_warning_delay_s: + type: integer + type: object + useragent: + properties: + delete_key: + type: boolean + flatten: + type: boolean + key_name: + type: string + out_key: + type: string + type: object + type: object + type: array + flowLabel: + type: string + globalOutputRefs: + items: + type: string + type: array + includeLabelInRouter: + type: boolean + outputRefs: + items: + type: string + type: array + type: object + enableRecreateWorkloadOnImmutableFieldChange: + type: boolean + errorOutputRef: + type: string + flowConfigCheckDisabled: + type: boolean + flowConfigOverride: + type: string + fluentbit: + properties: + HostNetwork: + type: boolean + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + bufferStorage: + properties: + storage.backlog.mem_limit: + type: string + storage.checksum: + type: string + storage.delete_irrecoverable_chunks: + type: string + storage.metrics: + type: string + storage.path: + type: string + storage.sync: + type: string + type: object + bufferStorageVolume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + bufferVolumeArgs: + items: + type: string + type: array + bufferVolumeImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + bufferVolumeMetrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + bufferVolumeResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + configHotReload: + properties: + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + coroStackSize: + format: int32 + type: integer + customConfigSecret: + type: string + customParsers: + type: string + daemonsetAnnotations: + additionalProperties: + type: string + type: object + disableKubernetesFilter: + type: boolean + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableUpstream: + type: boolean + envVars: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + extraVolumeMounts: + items: + properties: + destination: + pattern: ^/.+$ + type: string + readOnly: + type: boolean + source: + pattern: ^/.+$ + type: string + required: + - destination + - source + type: object + type: array + filterAws: + properties: + Match: + type: string + account_id: + type: boolean + ami_id: + type: boolean + az: + type: boolean + ec2_instance_id: + type: boolean + ec2_instance_type: + type: boolean + hostname: + type: boolean + imds_version: + type: string + private_ip: + type: boolean + vpc_id: + type: boolean + type: object + filterKubernetes: + properties: + Annotations: + type: string + Buffer_Size: + type: string + Cache_Use_Docker_Id: + type: string + DNS_Retries: + type: string + DNS_Wait_Time: + type: string + Dummy_Meta: + type: string + K8S-Logging.Exclude: + type: string + K8S-Logging.Parser: + type: string + Keep_Log: + type: string + Kube_CA_File: + type: string + Kube_CA_Path: + type: string + Kube_Meta_Cache_TTL: + type: string + Kube_Tag_Prefix: + type: string + Kube_Token_File: + type: string + Kube_Token_TTL: + type: string + Kube_URL: + type: string + Kube_meta_preload_cache_dir: + type: string + Kubelet_Port: + type: string + Labels: + type: string + Match: + type: string + Merge_Log: + type: string + Merge_Log_Key: + type: string + Merge_Log_Trim: + type: string + Merge_Parser: + type: string + Regex_Parser: + type: string + Use_Journal: + type: string + Use_Kubelet: + type: string + kube_meta_namespace_cache_ttl: + type: string + namespace_annotations: + type: string + namespace_labels: + type: string + tls.debug: + type: string + tls.verify: + type: string + type: object + filterModify: + items: + properties: + conditions: + items: + properties: + A_key_matches: + properties: + key: + type: string + type: object + Key_does_not_exist: + properties: + key: + type: string + value: + type: string + type: object + Key_exists: + properties: + key: + type: string + type: object + Key_value_does_not_equal: + properties: + key: + type: string + value: + type: string + type: object + Key_value_does_not_match: + properties: + key: + type: string + value: + type: string + type: object + Key_value_equals: + properties: + key: + type: string + value: + type: string + type: object + Key_value_matches: + properties: + key: + type: string + value: + type: string + type: object + Matching_keys_do_not_have_matching_values: + properties: + key: + type: string + value: + type: string + type: object + Matching_keys_have_matching_values: + properties: + key: + type: string + value: + type: string + type: object + No_key_matches: + properties: + key: + type: string + type: object + type: object + type: array + rules: + items: + properties: + Add: + properties: + key: + type: string + value: + type: string + type: object + Copy: + properties: + key: + type: string + value: + type: string + type: object + Hard_copy: + properties: + key: + type: string + value: + type: string + type: object + Hard_rename: + properties: + key: + type: string + value: + type: string + type: object + Remove: + properties: + key: + type: string + type: object + Remove_regex: + properties: + key: + type: string + type: object + Remove_wildcard: + properties: + key: + type: string + type: object + Rename: + properties: + key: + type: string + value: + type: string + type: object + Set: + properties: + key: + type: string + value: + type: string + type: object + type: object + type: array + type: object + type: array + flush: + format: int32 + type: integer + forwardOptions: + properties: + Require_ack_response: + type: boolean + Retry_Limit: + type: string + Send_options: + type: boolean + Tag: + type: string + Time_as_Integer: + type: boolean + Workers: + type: integer + storage.total_limit_size: + type: string + type: object + grace: + format: int32 + type: integer + healthCheck: + properties: + hcErrorsCount: + type: integer + hcPeriod: + type: integer + hcRetryFailureCount: + type: integer + type: object + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + inputTail: + properties: + Buffer_Chunk_Size: + type: string + Buffer_Max_Size: + type: string + DB: + type: string + DB.journal_mode: + type: string + DB.locking: + type: boolean + DB_Sync: + type: string + Docker_Mode: + type: string + Docker_Mode_Flush: + type: string + Docker_Mode_Parser: + type: string + Exclude_Path: + type: string + Ignore_Older: + type: string + Key: + type: string + Mem_Buf_Limit: + type: string + Multiline: + type: string + Multiline_Flush: + type: string + Parser: + type: string + Parser_Firstline: + type: string + Parser_N: + items: + type: string + type: array + Path: + type: string + Path_Key: + type: string + Read_From_Head: + type: boolean + Refresh_Interval: + type: string + Rotate_Wait: + type: string + Skip_Long_Lines: + type: string + Tag: + type: string + Tag_Regex: + type: string + multiline.parser: + items: + type: string + type: array + storage.type: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + livenessDefaultCheck: + type: boolean + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + logLevel: + type: string + loggingRef: + type: string + metrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + mountPath: + type: string + network: + properties: + connectTimeout: + format: int32 + type: integer + connectTimeoutLogError: + type: boolean + dnsMode: + type: string + dnsPreferIpv4: + type: boolean + dnsResolver: + type: string + keepalive: + type: boolean + keepaliveIdleTimeout: + format: int32 + type: integer + keepaliveMaxRecycle: + format: int32 + type: integer + maxWorkerConnections: + type: integer + sourceAddress: + type: string + type: object + nodeSelector: + additionalProperties: + type: string + type: object + parser: + type: string + podPriorityClassName: + type: string + position_db: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + positiondb: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + security: + properties: + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + podSecurityPolicyCreate: + type: boolean + roleBasedAccessControlCreate: + type: boolean + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + type: object + serviceAccount: + properties: + automountServiceAccountToken: + type: boolean + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + secrets: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + type: object + syslogng_output: + properties: + Retry_Limit: + type: string + Workers: + type: integer + json_date_format: + type: string + json_date_key: + type: string + type: object + targetHost: + type: string + targetPort: + format: int32 + type: integer + tls: + properties: + enabled: + type: boolean + secretName: + type: string + sharedKey: + type: string + required: + - enabled + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + updateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + fluentd: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + bufferStorageVolume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + bufferVolumeArgs: + items: + type: string + type: array + bufferVolumeImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + bufferVolumeMetrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + bufferVolumeResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + compressConfigFile: + type: boolean + configCheck: + properties: + labels: + additionalProperties: + type: string + type: object + strategy: + type: string + timeoutSeconds: + type: integer + type: object + configCheckAnnotations: + additionalProperties: + type: string + type: object + configCheckResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + configReloaderImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + configReloaderResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + disablePvc: + type: boolean + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableMsgpackTimeSupport: + type: boolean + envVars: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + extraArgs: + items: + type: string + type: array + extraVolumes: + items: + properties: + containerName: + type: string + path: + type: string + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeName: + type: string + type: object + type: array + fluentLogDestination: + type: string + fluentOutLogrotate: + properties: + age: + type: string + enabled: + type: boolean + path: + type: string + size: + type: string + required: + - enabled + type: object + fluentdPvcSpec: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + forwardInputConfig: + properties: + add_tag_prefix: + type: string + bind: + type: string + chunk_size_limit: + type: string + chunk_size_warn_limit: + type: string + deny_keepalive: + type: boolean + linger_timeout: + type: integer + port: + type: string + resolve_hostname: + type: boolean + security: + properties: + allow_anonymous_source: + type: boolean + self_hostname: + type: string + shared_key: + type: string + user_auth: + type: boolean + required: + - self_hostname + - shared_key + type: object + send_keepalive_packet: + type: boolean + skip_invalid_event: + type: boolean + source_address_key: + type: string + sourceHostnameKey: + type: string + tag: + type: string + transport: + properties: + ca_cert_path: + type: string + ca_path: + type: string + ca_private_key_passphrase: + type: string + ca_private_key_path: + type: string + cert_path: + type: string + ciphers: + type: string + client_cert_auth: + type: boolean + insecure: + type: boolean + private_key_passphrase: + type: string + private_key_path: + type: string + protocol: + type: string + version: + type: string + type: object + type: object + ignoreRepeatedLogInterval: + type: string + ignoreSameLogInterval: + type: string + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + livenessDefaultCheck: + type: boolean + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + logFormat: + type: string + logLevel: + type: string + metrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pdb: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + unhealthyPodEvictionPolicy: + type: string + type: object + podPriorityClassName: + type: string + port: + format: int32 + type: integer + readinessDefaultCheck: + properties: + bufferFileNumber: + type: boolean + bufferFileNumberMax: + format: int32 + type: integer + bufferFreeSpace: + type: boolean + bufferFreeSpaceThreshold: + format: int32 + type: integer + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + rootDir: + type: string + scaling: + properties: + drain: + properties: + annotations: + additionalProperties: + type: string + type: object + deleteVolume: + type: boolean + enabled: + type: boolean + image: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + pauseImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + podManagementPolicy: + type: string + replicas: + type: integer + type: object + security: + properties: + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + podSecurityPolicyCreate: + type: boolean + roleBasedAccessControlCreate: + type: boolean + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + type: object + serviceAccount: + properties: + automountServiceAccountToken: + type: boolean + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + secrets: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + type: object + sidecarContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + statefulsetAnnotations: + additionalProperties: + type: string + type: object + tls: + properties: + enabled: + type: boolean + secretName: + type: string + sharedKey: + type: string + required: + - enabled + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + volumeModImage: + properties: + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + pullPolicy: + type: string + repository: + type: string + tag: + type: string + type: object + volumeMountChmod: + type: boolean + workers: + format: int32 + type: integer + type: object + globalFilters: + items: + properties: + concat: + properties: + continuous_line_regexp: + type: string + flush_interval: + type: integer + keep_partial_key: + type: boolean + keep_partial_metadata: + type: string + key: + type: string + multiline_end_regexp: + type: string + multiline_start_regexp: + type: string + n_lines: + type: integer + partial_cri_logtag_key: + type: string + partial_cri_stream_key: + type: string + partial_key: + type: string + partial_metadata_format: + type: string + partial_value: + type: string + separator: + type: string + stream_identity_key: + type: string + timeout_label: + type: string + use_first_timestamp: + type: boolean + use_partial_cri_logtag: + type: boolean + use_partial_metadata: + type: string + type: object + dedot: + properties: + de_dot_nested: + type: boolean + de_dot_separator: + type: string + type: object + detectExceptions: + properties: + force_line_breaks: + type: boolean + languages: + items: + type: string + type: array + match_tag: + type: string + max_bytes: + type: integer + max_lines: + type: integer + message: + type: string + multiline_flush_interval: + type: string + remove_tag_prefix: + type: string + stream: + type: string + type: object + elasticsearch_genid: + properties: + hash_id_key: + type: string + hash_type: + type: string + include_tag_in_seed: + type: boolean + include_time_in_seed: + type: boolean + record_keys: + type: string + separator: + type: string + use_entire_record: + type: boolean + use_record_as_seed: + type: boolean + type: object + enhanceK8s: + properties: + api_groups: + items: + type: string + type: array + bearer_token_file: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cache_refresh: + type: integer + cache_refresh_variation: + type: integer + cache_size: + type: integer + cache_ttl: + type: integer + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + core_api_versions: + items: + type: string + type: array + data_type: + type: string + in_namespace_path: + items: + type: string + type: array + in_pod_path: + items: + type: string + type: array + kubernetes_url: + type: string + secret_dir: + type: string + ssl_partial_chain: + type: boolean + verify_ssl: + type: boolean + type: object + geoip: + properties: + backend_library: + type: string + geoip_database: + type: string + geoip_lookup_keys: + type: string + geoip2_database: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + skip_adding_null_record: + type: boolean + type: object + grep: + properties: + and: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + or: + items: + properties: + exclude: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + type: array + regexp: + items: + properties: + key: + type: string + pattern: + type: string + required: + - key + - pattern + type: object + type: array + type: object + kube_events_timestamp: + properties: + mapped_time_key: + type: string + timestamp_fields: + items: + type: string + type: array + type: object + parser: + properties: + emit_invalid_record_to_error: + type: boolean + hash_value_field: + type: string + inject_key_prefix: + type: string + key_name: + type: string + parse: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + parsers: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + delimiter: + type: string + delimiter_pattern: + type: string + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + format_firstline: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + keys: + type: string + label_delimiter: + type: string + local_time: + type: boolean + multiline: + items: + type: string + type: array + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + patterns: + items: + properties: + custom_pattern_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + estimate_current_event: + type: boolean + expression: + type: string + format: + type: string + grok_failure_key: + type: string + grok_name_key: + type: string + grok_pattern: + type: string + grok_patterns: + items: + properties: + keep_time_key: + type: boolean + name: + type: string + pattern: + type: string + time_format: + type: string + time_key: + type: string + timezone: + type: string + required: + - pattern + type: object + type: array + keep_time_key: + type: boolean + local_time: + type: boolean + multiline_start_regexp: + type: string + null_empty_string: + type: boolean + null_value_pattern: + type: string + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + time_format: + type: string + time_key: + type: string + time_type: + type: string + timezone: + type: string + type: + type: string + types: + type: string + utc: + type: boolean + type: object + type: array + remove_key_name_field: + type: boolean + replace_invalid_sequence: + type: boolean + reserve_data: + type: boolean + reserve_time: + type: boolean + type: object + prometheus: + properties: + labels: + additionalProperties: + type: string + type: object + metrics: + items: + properties: + buckets: + type: string + desc: + type: string + key: + type: string + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: + type: string + required: + - desc + - name + - type + type: object + type: array + type: object + record_modifier: + properties: + char_encoding: + type: string + prepare_value: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + replaces: + items: + properties: + expression: + type: string + key: + type: string + replace: + type: string + required: + - expression + - key + - replace + type: object + type: array + whitelist_keys: + type: string + type: object + record_transformer: + properties: + auto_typecast: + type: boolean + enable_ruby: + type: boolean + keep_keys: + type: string + records: + items: + additionalProperties: + type: string + type: object + type: array + remove_keys: + type: string + renew_record: + type: boolean + renew_time_key: + type: string + type: object + stdout: + properties: + output_type: + type: string + type: object + sumologic: + properties: + collector_key_name: + type: string + collector_value: + type: string + exclude_container_regex: + type: string + exclude_facility_regex: + type: string + exclude_host_regex: + type: string + exclude_namespace_regex: + type: string + exclude_pod_regex: + type: string + exclude_priority_regex: + type: string + exclude_unit_regex: + type: string + log_format: + type: string + source_category: + type: string + source_category_key_name: + type: string + source_category_prefix: + type: string + source_category_replace_dash: + type: string + source_host: + type: string + source_host_key_name: + type: string + source_name: + type: string + source_name_key_name: + type: string + tracing_annotation_prefix: + type: string + tracing_container_name: + type: string + tracing_format: + type: boolean + tracing_host: + type: string + tracing_label_prefix: + type: string + tracing_namespace: + type: string + tracing_pod: + type: string + tracing_pod_id: + type: string + type: object + tag_normaliser: + properties: + format: + type: string + match_tag: + type: string + type: object + throttle: + properties: + group_bucket_limit: + type: integer + group_bucket_period_s: + type: integer + group_drop_logs: + type: boolean + group_key: + type: string + group_reset_rate_s: + type: integer + group_warning_delay_s: + type: integer + type: object + useragent: + properties: + delete_key: + type: boolean + flatten: + type: boolean + key_name: + type: string + out_key: + type: string + type: object + type: object + type: array + loggingRef: + type: string + nodeAgents: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + nodeAgentFluentbit: + properties: + bufferStorage: + properties: + storage.backlog.mem_limit: + type: string + storage.checksum: + type: string + storage.delete_irrecoverable_chunks: + type: string + storage.metrics: + type: string + storage.path: + type: string + storage.sync: + type: string + type: object + bufferStorageVolume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + containersPath: + type: string + coroStackSize: + format: int32 + type: integer + customConfigSecret: + type: string + daemonSet: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + minReadySeconds: + format: int32 + type: integer + revisionHistoryLimit: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + updateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + type: object + disableKubernetesFilter: + type: boolean + enableUpstream: + type: boolean + enabled: + type: boolean + extraVolumeMounts: + items: + properties: + destination: + pattern: ^/.+$ + type: string + readOnly: + type: boolean + source: + pattern: ^/.+$ + type: string + required: + - destination + - source + type: object + type: array + filterAws: + properties: + Match: + type: string + account_id: + type: boolean + ami_id: + type: boolean + az: + type: boolean + ec2_instance_id: + type: boolean + ec2_instance_type: + type: boolean + hostname: + type: boolean + imds_version: + type: string + private_ip: + type: boolean + vpc_id: + type: boolean + type: object + filterKubernetes: + properties: + Annotations: + type: string + Buffer_Size: + type: string + Cache_Use_Docker_Id: + type: string + DNS_Retries: + type: string + DNS_Wait_Time: + type: string + Dummy_Meta: + type: string + K8S-Logging.Exclude: + type: string + K8S-Logging.Parser: + type: string + Keep_Log: + type: string + Kube_CA_File: + type: string + Kube_CA_Path: + type: string + Kube_Meta_Cache_TTL: + type: string + Kube_Tag_Prefix: + type: string + Kube_Token_File: + type: string + Kube_Token_TTL: + type: string + Kube_URL: + type: string + Kube_meta_preload_cache_dir: + type: string + Kubelet_Port: + type: string + Labels: + type: string + Match: + type: string + Merge_Log: + type: string + Merge_Log_Key: + type: string + Merge_Log_Trim: + type: string + Merge_Parser: + type: string + Regex_Parser: + type: string + Use_Journal: + type: string + Use_Kubelet: + type: string + kube_meta_namespace_cache_ttl: + type: string + namespace_annotations: + type: string + namespace_labels: + type: string + tls.debug: + type: string + tls.verify: + type: string + type: object + flush: + format: int32 + type: integer + forwardOptions: + properties: + Require_ack_response: + type: boolean + Retry_Limit: + type: string + Send_options: + type: boolean + Tag: + type: string + Time_as_Integer: + type: boolean + Workers: + type: integer + storage.total_limit_size: + type: string + type: object + grace: + format: int32 + type: integer + inputTail: + properties: + Buffer_Chunk_Size: + type: string + Buffer_Max_Size: + type: string + DB: + type: string + DB.journal_mode: + type: string + DB.locking: + type: boolean + DB_Sync: + type: string + Docker_Mode: + type: string + Docker_Mode_Flush: + type: string + Docker_Mode_Parser: + type: string + Exclude_Path: + type: string + Ignore_Older: + type: string + Key: + type: string + Mem_Buf_Limit: + type: string + Multiline: + type: string + Multiline_Flush: + type: string + Parser: + type: string + Parser_Firstline: + type: string + Parser_N: + items: + type: string + type: array + Path: + type: string + Path_Key: + type: string + Read_From_Head: + type: boolean + Refresh_Interval: + type: string + Rotate_Wait: + type: string + Skip_Long_Lines: + type: string + Tag: + type: string + Tag_Regex: + type: string + multiline.parser: + items: + type: string + type: array + storage.type: + type: string + type: object + livenessDefaultCheck: + type: boolean + logLevel: + type: string + metrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + metricsService: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + trafficDistribution: + type: string + type: + type: string + type: object + type: object + network: + properties: + connectTimeout: + format: int32 + type: integer + connectTimeoutLogError: + type: boolean + dnsMode: + type: string + dnsPreferIpv4: + type: boolean + dnsResolver: + type: string + keepalive: + type: boolean + keepaliveIdleTimeout: + format: int32 + type: integer + keepaliveMaxRecycle: + format: int32 + type: integer + maxWorkerConnections: + type: integer + sourceAddress: + type: string + type: object + podPriorityClassName: + type: string + positiondb: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + security: + properties: + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + podSecurityPolicyCreate: + type: boolean + roleBasedAccessControlCreate: + type: boolean + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + type: object + serviceAccount: + properties: + automountServiceAccountToken: + type: boolean + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + secrets: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + type: object + targetHost: + type: string + targetPort: + format: int32 + type: integer + tls: + properties: + enabled: + type: boolean + secretName: + type: string + sharedKey: + type: string + required: + - enabled + type: object + varLogsPath: + type: string + type: object + profile: + type: string + type: object + type: array + skipInvalidResources: + type: boolean + syslogNG: + properties: + bufferVolumeMetrics: + properties: + interval: + type: string + mount_name: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + bufferVolumeMetricsService: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + trafficDistribution: + type: string + type: + type: string + type: object + type: object + configCheck: + properties: + labels: + additionalProperties: + type: string + type: object + strategy: + type: string + timeoutSeconds: + type: integer + type: object + configCheckPod: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + globalOptions: + properties: + log_level: + type: string + stats: + properties: + freq: + type: integer + level: + type: integer + type: object + stats_freq: + type: integer + stats_level: + type: integer + type: object + jsonKeyDelim: + type: string + jsonKeyPrefix: + type: string + logIWSize: + type: integer + maxConnections: + type: integer + metrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + metricsService: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + trafficDistribution: + type: string + type: + type: string + type: object + type: object + readinessDefaultCheck: + properties: + bufferFileNumber: + type: boolean + bufferFileNumberMax: + format: int32 + type: integer + bufferFreeSpace: + type: boolean + bufferFreeSpaceThreshold: + format: int32 + type: integer + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + trafficDistribution: + type: string + type: + type: string + type: object + type: object + serviceAccount: + properties: + automountServiceAccountToken: + type: boolean + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + secrets: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + type: object + skipRBACCreate: + type: boolean + sourceDateParser: + properties: + format: + type: string + template: + type: string + type: object + sourceMetrics: + items: + properties: + key: + type: string + labels: + additionalProperties: + type: string + type: object + level: + type: integer + type: object + type: array + statefulSet: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + podManagementPolicy: + type: string + replicas: + format: int32 + type: integer + revisionHistoryLimit: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + serviceName: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + updateStrategy: + properties: + rollingUpdate: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + partition: + format: int32 + type: integer + type: object + type: + type: string + type: object + volumeClaimTemplates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: array + type: object + type: object + tls: + properties: + enabled: + type: boolean + secretName: + type: string + sharedKey: + type: string + required: + - enabled + type: object + type: object + watchNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + watchNamespaces: + items: + type: string + type: array + required: + - controlNamespace + type: object + status: + properties: + configCheckResults: + additionalProperties: + type: boolean + type: object + fluentdConfigName: + type: string + problems: + items: + type: string + type: array + problemsCount: + type: integer + syslogNGConfigName: + type: string + watchNamespaces: + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_nodeagents.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_nodeagents.yaml new file mode 100644 index 0000000000..beb6c35389 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_nodeagents.yaml @@ -0,0 +1,4788 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: nodeagents.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: NodeAgent + listKind: NodeAgentList + plural: nodeagents + singular: nodeagent + scope: Cluster + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + loggingRef: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeAgentFluentbit: + properties: + bufferStorage: + properties: + storage.backlog.mem_limit: + type: string + storage.checksum: + type: string + storage.delete_irrecoverable_chunks: + type: string + storage.metrics: + type: string + storage.path: + type: string + storage.sync: + type: string + type: object + bufferStorageVolume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + containersPath: + type: string + coroStackSize: + format: int32 + type: integer + customConfigSecret: + type: string + daemonSet: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + minReadySeconds: + format: int32 + type: integer + revisionHistoryLimit: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + updateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + type: object + disableKubernetesFilter: + type: boolean + enableUpstream: + type: boolean + enabled: + type: boolean + extraVolumeMounts: + items: + properties: + destination: + pattern: ^/.+$ + type: string + readOnly: + type: boolean + source: + pattern: ^/.+$ + type: string + required: + - destination + - source + type: object + type: array + filterAws: + properties: + Match: + type: string + account_id: + type: boolean + ami_id: + type: boolean + az: + type: boolean + ec2_instance_id: + type: boolean + ec2_instance_type: + type: boolean + hostname: + type: boolean + imds_version: + type: string + private_ip: + type: boolean + vpc_id: + type: boolean + type: object + filterKubernetes: + properties: + Annotations: + type: string + Buffer_Size: + type: string + Cache_Use_Docker_Id: + type: string + DNS_Retries: + type: string + DNS_Wait_Time: + type: string + Dummy_Meta: + type: string + K8S-Logging.Exclude: + type: string + K8S-Logging.Parser: + type: string + Keep_Log: + type: string + Kube_CA_File: + type: string + Kube_CA_Path: + type: string + Kube_Meta_Cache_TTL: + type: string + Kube_Tag_Prefix: + type: string + Kube_Token_File: + type: string + Kube_Token_TTL: + type: string + Kube_URL: + type: string + Kube_meta_preload_cache_dir: + type: string + Kubelet_Port: + type: string + Labels: + type: string + Match: + type: string + Merge_Log: + type: string + Merge_Log_Key: + type: string + Merge_Log_Trim: + type: string + Merge_Parser: + type: string + Regex_Parser: + type: string + Use_Journal: + type: string + Use_Kubelet: + type: string + kube_meta_namespace_cache_ttl: + type: string + namespace_annotations: + type: string + namespace_labels: + type: string + tls.debug: + type: string + tls.verify: + type: string + type: object + flush: + format: int32 + type: integer + forwardOptions: + properties: + Require_ack_response: + type: boolean + Retry_Limit: + type: string + Send_options: + type: boolean + Tag: + type: string + Time_as_Integer: + type: boolean + Workers: + type: integer + storage.total_limit_size: + type: string + type: object + grace: + format: int32 + type: integer + inputTail: + properties: + Buffer_Chunk_Size: + type: string + Buffer_Max_Size: + type: string + DB: + type: string + DB.journal_mode: + type: string + DB.locking: + type: boolean + DB_Sync: + type: string + Docker_Mode: + type: string + Docker_Mode_Flush: + type: string + Docker_Mode_Parser: + type: string + Exclude_Path: + type: string + Ignore_Older: + type: string + Key: + type: string + Mem_Buf_Limit: + type: string + Multiline: + type: string + Multiline_Flush: + type: string + Parser: + type: string + Parser_Firstline: + type: string + Parser_N: + items: + type: string + type: array + Path: + type: string + Path_Key: + type: string + Read_From_Head: + type: boolean + Refresh_Interval: + type: string + Rotate_Wait: + type: string + Skip_Long_Lines: + type: string + Tag: + type: string + Tag_Regex: + type: string + multiline.parser: + items: + type: string + type: array + storage.type: + type: string + type: object + livenessDefaultCheck: + type: boolean + logLevel: + type: string + metrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + metricsService: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + trafficDistribution: + type: string + type: + type: string + type: object + type: object + network: + properties: + connectTimeout: + format: int32 + type: integer + connectTimeoutLogError: + type: boolean + dnsMode: + type: string + dnsPreferIpv4: + type: boolean + dnsResolver: + type: string + keepalive: + type: boolean + keepaliveIdleTimeout: + format: int32 + type: integer + keepaliveMaxRecycle: + format: int32 + type: integer + maxWorkerConnections: + type: integer + sourceAddress: + type: string + type: object + podPriorityClassName: + type: string + positiondb: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + host_path: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + pvc: + properties: + source: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + type: object + security: + properties: + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + podSecurityPolicyCreate: + type: boolean + roleBasedAccessControlCreate: + type: boolean + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + type: object + serviceAccount: + properties: + automountServiceAccountToken: + type: boolean + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + secrets: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + type: object + targetHost: + type: string + targetPort: + format: int32 + type: integer + tls: + properties: + enabled: + type: boolean + secretName: + type: string + sharedKey: + type: string + required: + - enabled + type: object + varLogsPath: + type: string + type: object + profile: + type: string + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_outputs.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_outputs.yaml new file mode 100644 index 0000000000..222995229d --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_outputs.yaml @@ -0,0 +1,14078 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: outputs.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: Output + listKind: OutputList + plural: outputs + singular: output + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the output active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + awsElasticsearch: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + content_type: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_ilm_name: + type: string + data_stream_ilm_policy: + type: string + data_stream_ilm_policy_overwrite: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_elasticsearch_version: + type: string + deflector_alias: + type: string + enable_ilm: + type: boolean + endpoint: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_arn: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_session_name: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_web_identity_token_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ecs_container_credentials_relative_uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + region: + type: string + secret_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + sts_credentials_region: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + type: object + exception_backup: + type: boolean + fail_on_detecting_es_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + flush_interval: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + host: + type: string + hosts: + type: string + http_backend: + type: string + id_key: + type: string + ignore_exceptions: + type: string + ilm_policy: + type: string + ilm_policy_id: + type: string + ilm_policy_overwrite: + type: boolean + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_prefix: + type: string + log_es_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_es_version: + type: string + max_retry_putting_template: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys: + type: string + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + rollover_index: + type: boolean + routing_key: + type: string + scheme: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_max_version: + type: string + ssl_min_version: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_key: + type: string + target_type_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + type_name: + type: string + unrecoverable_error_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_es_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + azurestorage: + properties: + auto_create_container: + type: boolean + azure_cloud: + type: string + azure_container: + type: string + azure_imds_api_version: + type: string + azure_object_key_format: + type: string + azure_storage_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + azure_storage_account: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + azure_storage_sas_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + type: string + path: + type: string + slow_flush_log_threshold: + type: string + required: + - azure_container + - azure_storage_account + type: object + cloudwatch: + properties: + auto_create_stream: + type: boolean + aws_instance_profile_credentials_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sts_role_arn: + type: string + aws_sts_session_name: + type: string + aws_use_sts: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + concurrency: + type: integer + endpoint: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + http_proxy: + type: string + include_time_key: + type: boolean + json_handler: + type: string + localtime: + type: boolean + log_group_aws_tags: + type: string + log_group_aws_tags_key: + type: string + log_group_name: + type: string + log_group_name_key: + type: string + log_rejected_request: + type: string + log_stream_name: + type: string + log_stream_name_key: + type: string + max_events_per_batch: + type: integer + max_message_length: + type: integer + message_keys: + type: string + put_log_events_disable_retry_limit: + type: boolean + put_log_events_retry_limit: + type: integer + put_log_events_retry_wait: + type: string + region: + type: string + remove_log_group_aws_tags_key: + type: string + remove_log_group_name_key: + type: string + remove_log_stream_name_key: + type: string + remove_retention_in_days: + type: string + retention_in_days: + type: string + retention_in_days_key: + type: string + slow_flush_log_threshold: + type: string + use_tag_as_group: + type: boolean + use_tag_as_stream: + type: boolean + required: + - region + type: object + datadog: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compression_level: + type: string + dd_hostname: + type: string + dd_source: + type: string + dd_sourcecategory: + type: string + dd_tags: + type: string + host: + type: string + include_tag_key: + type: boolean + max_backoff: + type: string + max_retries: + type: string + no_ssl_validation: + type: boolean + port: + type: string + service: + type: string + slow_flush_log_threshold: + type: string + ssl_port: + type: string + tag_key: + type: string + timestamp_key: + type: string + use_compression: + type: boolean + use_http: + type: boolean + use_json: + type: boolean + use_ssl: + type: boolean + required: + - api_key + type: object + elasticsearch: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + content_type: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_ilm_name: + type: string + data_stream_ilm_policy: + type: string + data_stream_ilm_policy_overwrite: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_elasticsearch_version: + type: string + deflector_alias: + type: string + enable_ilm: + type: boolean + exception_backup: + type: boolean + fail_on_detecting_es_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + hosts: + type: string + http_backend: + type: string + id_key: + type: string + ignore_exceptions: + type: string + ilm_policy: + type: string + ilm_policy_id: + type: string + ilm_policy_overwrite: + type: boolean + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_prefix: + type: string + log_es_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_es_version: + type: string + max_retry_putting_template: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys: + type: string + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + rollover_index: + type: boolean + routing_key: + type: string + scheme: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_max_version: + type: string + ssl_min_version: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_key: + type: string + target_type_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + type_name: + type: string + unrecoverable_error_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_es_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + file: + properties: + add_path_suffix: + type: boolean + append: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compress: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + path: + type: string + path_suffix: + type: string + recompress: + type: boolean + slow_flush_log_threshold: + type: string + symlink_path: + type: boolean + required: + - path + type: object + forward: + properties: + ack_response_timeout: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + connect_timeout: + type: integer + dns_round_robin: + type: boolean + expire_dns_cache: + type: integer + hard_timeout: + type: integer + heartbeat_interval: + type: integer + heartbeat_type: + type: string + ignore_network_errors_at_startup: + type: boolean + keepalive: + type: boolean + keepalive_timeout: + type: integer + phi_failure_detector: + type: boolean + phi_threshold: + type: integer + recover_wait: + type: integer + require_ack_response: + type: boolean + security: + properties: + allow_anonymous_source: + type: boolean + self_hostname: + type: string + shared_key: + type: string + user_auth: + type: boolean + required: + - self_hostname + - shared_key + type: object + send_timeout: + type: integer + servers: + items: + properties: + host: + type: string + name: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + type: integer + shared_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + standby: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + weight: + type: integer + required: + - host + type: object + type: array + slow_flush_log_threshold: + type: string + time_as_integer: + type: boolean + tls_allow_self_signed_cert: + type: boolean + tls_cert_logical_store_name: + type: string + tls_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_cert_thumbprint: + type: string + tls_cert_use_enterprise_store: + type: boolean + tls_ciphers: + type: string + tls_client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_client_private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_client_private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_insecure_mode: + type: boolean + tls_verify_hostname: + type: boolean + tls_version: + type: string + transport: + type: string + verify_connection_at_startup: + type: boolean + required: + - servers + type: object + gcs: + properties: + acl: + type: string + auto_create_bucket: + type: boolean + bucket: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_retries: + type: integer + client_timeout: + type: integer + credentials_json: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + encryption_key: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hex_random_length: + type: integer + keyfile: + type: string + object_key_format: + type: string + object_metadata: + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + overwrite: + type: boolean + path: + type: string + project: + type: string + slow_flush_log_threshold: + type: string + storage_class: + type: string + store_as: + type: string + transcoding: + type: boolean + required: + - bucket + - project + type: object + gelf: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + host: + type: string + port: + type: integer + protocol: + type: string + tls: + type: boolean + tls_options: + additionalProperties: + type: string + type: object + required: + - host + - port + type: object + http: + properties: + auth: + properties: + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - password + - username + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + content_type: + type: string + endpoint: + type: string + error_response_as_unrecoverable: + type: boolean + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + headers: + additionalProperties: + type: string + type: object + http_method: + type: string + json_array: + type: boolean + open_timeout: + type: integer + proxy: + type: string + read_timeout: + type: integer + retryable_response_codes: + items: + type: integer + type: array + slow_flush_log_threshold: + type: string + ssl_timeout: + type: integer + tls_ca_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_ciphers: + type: string + tls_client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_verify_mode: + type: string + tls_version: + type: string + required: + - endpoint + type: object + kafka: + properties: + ack_timeout: + type: integer + brokers: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_id: + type: string + compression_codec: + type: string + default_message_key: + type: string + default_partition_key: + type: string + default_topic: + type: string + discard_kafka_delivery_failed: + type: boolean + exclude_partion_key: + type: boolean + exclude_topic_key: + type: boolean + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + get_kafka_client_log: + type: boolean + headers: + additionalProperties: + type: string + type: object + headers_from_record: + additionalProperties: + type: string + type: object + idempotent: + type: boolean + kafka_agg_max_bytes: + type: integer + kafka_agg_max_messages: + type: integer + keytab: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + max_send_retries: + type: integer + message_key_key: + type: string + partition_key: + type: string + partition_key_key: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + principal: + type: string + required_acks: + type: integer + sasl_over_ssl: + type: boolean + scram_mechanism: + type: string + slow_flush_log_threshold: + type: string + ssl_ca_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_ca_certs_from_system: + type: boolean + ssl_client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_client_cert_chain: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_client_cert_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_verify_hostname: + type: boolean + topic_key: + type: string + use_default_for_unknown_topic: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - brokers + - format + type: object + kinesisStream: + properties: + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + aws_iam_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_ses_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch_request_max_count: + type: integer + batch_request_max_size: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + partition_key: + type: string + process_credentials: + properties: + process: + type: string + required: + - process + type: object + region: + type: string + reset_backoff_if_success: + type: boolean + retries_on_batch_request: + type: integer + slow_flush_log_threshold: + type: string + stream_name: + type: string + required: + - stream_name + type: object + logdna: + properties: + api_key: + type: string + app: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + hostname: + type: string + ingester_domain: + type: string + ingester_endpoint: + type: string + request_timeout: + type: string + slow_flush_log_threshold: + type: string + tags: + type: string + required: + - api_key + - hostname + type: object + loggingRef: + type: string + logz: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_limit: + type: integer + bulk_limit_warning_limit: + type: integer + endpoint: + properties: + port: + type: integer + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + type: object + gzip: + type: boolean + http_idle_timeout: + type: integer + output_include_tags: + type: boolean + output_include_time: + type: boolean + retry_count: + type: integer + retry_sleep: + type: integer + slow_flush_log_threshold: + type: string + required: + - endpoint + type: object + loki: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + configure_kubernetes_labels: + type: boolean + drop_single_key: + type: boolean + extra_labels: + additionalProperties: + type: string + type: object + extract_kubernetes_labels: + type: boolean + include_thread_label: + type: boolean + insecure_tls: + type: boolean + key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + labels: + additionalProperties: + type: string + type: object + line_format: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + remove_keys: + items: + type: string + type: array + slow_flush_log_threshold: + type: string + tenant: + type: string + url: + type: string + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + newrelic: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + base_uri: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + license_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + nullout: + type: object + opensearch: + properties: + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + catch_transport_exception_on_retry: + type: boolean + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_opensearch_version: + type: integer + emit_error_for_missing_id: + type: boolean + emit_error_label_event: + type: boolean + endpoint: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_arn: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_session_name: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_web_identity_token_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ecs_container_credentials_relative_uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + region: + type: string + secret_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + sts_credentials_region: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + required: + - url + type: object + exception_backup: + type: boolean + fail_on_detecting_os_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + hosts: + type: string + http_backend: + type: string + http_backend_excon_nonblock: + type: boolean + id_key: + type: string + ignore_exceptions: + type: string + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_separator: + type: string + log_os_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_os_version: + type: integer + max_retry_putting_template: + type: string + parent_key: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + routing_key: + type: string + scheme: + type: string + selector_class_name: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_affinity: + type: boolean + target_index_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_exclude_timestamp: + type: boolean + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + truncate_caches_interval: + type: string + unrecoverable_error_types: + type: string + unrecoverable_record_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_os_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + oss: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + access_key_secret: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + auto_create_bucket: + type: boolean + bucket: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + check_bucket: + type: boolean + check_object: + type: boolean + download_crc_enable: + type: boolean + endpoint: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hex_random_length: + type: integer + index_format: + type: string + key_format: + type: string + open_timeout: + type: integer + oss_sdk_log_dir: + type: string + overwrite: + type: boolean + path: + type: string + read_timeout: + type: integer + slow_flush_log_threshold: + type: string + store_as: + type: string + upload_crc_enable: + type: boolean + warn_for_delay: + type: string + required: + - access_key_id + - access_key_secret + - bucket + - endpoint + type: object + redis: + properties: + allow_duplicate_key: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + db_number: + type: integer + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + host: + type: string + insert_key_prefix: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + type: integer + slow_flush_log_threshold: + type: string + strftime_format: + type: string + ttl: + type: integer + type: object + relabel: + properties: + label: + type: string + required: + - label + type: object + s3: + properties: + acl: + type: string + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + auto_create_bucket: + type: string + aws_iam_retries: + type: string + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + check_apikey_on_start: + type: string + check_bucket: + type: string + check_object: + type: string + clustername: + type: string + compress: + properties: + parquet_compression_codec: + type: string + parquet_page_size: + type: string + parquet_row_group_size: + type: string + record_type: + type: string + schema_file: + type: string + schema_type: + type: string + type: object + compute_checksums: + type: string + enable_transfer_acceleration: + type: string + force_path_style: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + grant_full_control: + type: string + grant_read: + type: string + grant_read_acp: + type: string + grant_write_acp: + type: string + hex_random_length: + type: string + index_format: + type: string + instance_profile_credentials: + properties: + http_open_timeout: + type: string + http_read_timeout: + type: string + ip_address: + type: string + port: + type: string + retries: + type: string + type: object + oneeye_format: + type: boolean + overwrite: + type: string + path: + type: string + proxy_uri: + type: string + s3_bucket: + type: string + s3_endpoint: + type: string + s3_metadata: + type: string + s3_object_key_format: + type: string + s3_region: + type: string + shared_credentials: + properties: + path: + type: string + profile_name: + type: string + type: object + signature_version: + type: string + slow_flush_log_threshold: + type: string + sse_customer_algorithm: + type: string + sse_customer_key: + type: string + sse_customer_key_md5: + type: string + ssekms_key_id: + type: string + ssl_verify_peer: + type: string + storage_class: + type: string + store_as: + type: string + use_bundled_cert: + type: string + use_server_side_encryption: + type: string + warn_for_delay: + type: string + required: + - s3_bucket + type: object + splunkHec: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + coerce_to_utf8: + type: boolean + data_type: + type: string + fields: + additionalProperties: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hec_host: + type: string + hec_port: + type: integer + hec_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + host: + type: string + host_key: + type: string + idle_timeout: + type: integer + index: + type: string + index_key: + type: string + insecure_ssl: + type: boolean + keep_keys: + type: boolean + metric_name_key: + type: string + metric_value_key: + type: string + metrics_from_event: + type: boolean + non_utf8_replacement_string: + type: string + open_timeout: + type: integer + protocol: + type: string + read_timeout: + type: integer + slow_flush_log_threshold: + type: string + source: + type: string + source_key: + type: string + sourcetype: + type: string + sourcetype_key: + type: string + ssl_ciphers: + type: string + required: + - hec_host + - hec_token + type: object + sqs: + properties: + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + create_queue: + type: boolean + delay_seconds: + type: integer + include_tag: + type: boolean + message_group_id: + type: string + queue_name: + type: string + region: + type: string + slow_flush_log_threshold: + type: string + sqs_url: + type: string + tag_property_name: + type: string + type: object + sumologic: + properties: + add_timestamp: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compress: + type: boolean + compress_encoding: + type: string + custom_dimensions: + type: string + custom_fields: + items: + type: string + type: array + data_type: + type: string + delimiter: + type: string + disable_cookies: + type: boolean + endpoint: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + log_format: + type: string + log_key: + type: string + metric_data_format: + type: string + open_timeout: + type: integer + proxy_uri: + type: string + slow_flush_log_threshold: + type: string + source_category: + type: string + source_host: + type: string + source_name: + type: string + source_name_key: + type: string + sumo_client: + type: string + timestamp_key: + type: string + verify_ssl: + type: boolean + required: + - endpoint + - source_name + type: object + syslog: + properties: + allow_self_signed_cert: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + enable_system_cert_store: + type: boolean + format: + properties: + app_name_field: + type: string + hostname_field: + type: string + log_field: + type: string + message_id_field: + type: string + proc_id_field: + type: string + rfc6587_message_size: + type: boolean + structured_data_field: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + fqdn: + type: string + host: + type: string + insecure: + type: boolean + port: + type: integer + private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + slow_flush_log_threshold: + type: string + transport: + type: string + trusted_ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + verify_fqdn: + type: boolean + version: + type: string + required: + - host + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Is the output active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + awsElasticsearch: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + content_type: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_ilm_name: + type: string + data_stream_ilm_policy: + type: string + data_stream_ilm_policy_overwrite: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_elasticsearch_version: + type: string + deflector_alias: + type: string + enable_ilm: + type: boolean + endpoint: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_arn: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_session_name: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_web_identity_token_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ecs_container_credentials_relative_uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + region: + type: string + secret_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + sts_credentials_region: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + type: object + exception_backup: + type: boolean + fail_on_detecting_es_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + flush_interval: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + host: + type: string + hosts: + type: string + http_backend: + type: string + id_key: + type: string + ignore_exceptions: + type: string + ilm_policy: + type: string + ilm_policy_id: + type: string + ilm_policy_overwrite: + type: boolean + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_prefix: + type: string + log_es_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_es_version: + type: string + max_retry_putting_template: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys: + type: string + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + rollover_index: + type: boolean + routing_key: + type: string + scheme: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_max_version: + type: string + ssl_min_version: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_key: + type: string + target_type_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + type_name: + type: string + unrecoverable_error_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_es_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + azurestorage: + properties: + auto_create_container: + type: boolean + azure_cloud: + type: string + azure_container: + type: string + azure_imds_api_version: + type: string + azure_object_key_format: + type: string + azure_storage_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + azure_storage_account: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + azure_storage_sas_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + type: string + path: + type: string + slow_flush_log_threshold: + type: string + required: + - azure_container + - azure_storage_account + type: object + cloudwatch: + properties: + auto_create_stream: + type: boolean + aws_instance_profile_credentials_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sts_role_arn: + type: string + aws_sts_session_name: + type: string + aws_use_sts: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + concurrency: + type: integer + endpoint: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + http_proxy: + type: string + include_time_key: + type: boolean + json_handler: + type: string + localtime: + type: boolean + log_group_aws_tags: + type: string + log_group_aws_tags_key: + type: string + log_group_name: + type: string + log_group_name_key: + type: string + log_rejected_request: + type: string + log_stream_name: + type: string + log_stream_name_key: + type: string + max_events_per_batch: + type: integer + max_message_length: + type: integer + message_keys: + type: string + put_log_events_disable_retry_limit: + type: boolean + put_log_events_retry_limit: + type: integer + put_log_events_retry_wait: + type: string + region: + type: string + remove_log_group_aws_tags_key: + type: string + remove_log_group_name_key: + type: string + remove_log_stream_name_key: + type: string + remove_retention_in_days: + type: string + retention_in_days: + type: string + retention_in_days_key: + type: string + slow_flush_log_threshold: + type: string + use_tag_as_group: + type: boolean + use_tag_as_stream: + type: boolean + required: + - region + type: object + datadog: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compression_level: + type: string + dd_hostname: + type: string + dd_source: + type: string + dd_sourcecategory: + type: string + dd_tags: + type: string + host: + type: string + include_tag_key: + type: boolean + max_backoff: + type: string + max_retries: + type: string + no_ssl_validation: + type: boolean + port: + type: string + service: + type: string + slow_flush_log_threshold: + type: string + ssl_port: + type: string + tag_key: + type: string + timestamp_key: + type: string + use_compression: + type: boolean + use_http: + type: boolean + use_json: + type: boolean + use_ssl: + type: boolean + required: + - api_key + type: object + elasticsearch: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + content_type: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_ilm_name: + type: string + data_stream_ilm_policy: + type: string + data_stream_ilm_policy_overwrite: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_elasticsearch_version: + type: string + deflector_alias: + type: string + enable_ilm: + type: boolean + exception_backup: + type: boolean + fail_on_detecting_es_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + hosts: + type: string + http_backend: + type: string + id_key: + type: string + ignore_exceptions: + type: string + ilm_policy: + type: string + ilm_policy_id: + type: string + ilm_policy_overwrite: + type: boolean + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_prefix: + type: string + log_es_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_es_version: + type: string + max_retry_putting_template: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys: + type: string + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + rollover_index: + type: boolean + routing_key: + type: string + scheme: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_max_version: + type: string + ssl_min_version: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_key: + type: string + target_type_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + type_name: + type: string + unrecoverable_error_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_es_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + file: + properties: + add_path_suffix: + type: boolean + append: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compress: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + path: + type: string + path_suffix: + type: string + recompress: + type: boolean + slow_flush_log_threshold: + type: string + symlink_path: + type: boolean + required: + - path + type: object + forward: + properties: + ack_response_timeout: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + connect_timeout: + type: integer + dns_round_robin: + type: boolean + expire_dns_cache: + type: integer + hard_timeout: + type: integer + heartbeat_interval: + type: integer + heartbeat_type: + type: string + ignore_network_errors_at_startup: + type: boolean + keepalive: + type: boolean + keepalive_timeout: + type: integer + phi_failure_detector: + type: boolean + phi_threshold: + type: integer + recover_wait: + type: integer + require_ack_response: + type: boolean + security: + properties: + allow_anonymous_source: + type: boolean + self_hostname: + type: string + shared_key: + type: string + user_auth: + type: boolean + required: + - self_hostname + - shared_key + type: object + send_timeout: + type: integer + servers: + items: + properties: + host: + type: string + name: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + type: integer + shared_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + standby: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + weight: + type: integer + required: + - host + type: object + type: array + slow_flush_log_threshold: + type: string + time_as_integer: + type: boolean + tls_allow_self_signed_cert: + type: boolean + tls_cert_logical_store_name: + type: string + tls_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_cert_thumbprint: + type: string + tls_cert_use_enterprise_store: + type: boolean + tls_ciphers: + type: string + tls_client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_client_private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_client_private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_insecure_mode: + type: boolean + tls_verify_hostname: + type: boolean + tls_version: + type: string + transport: + type: string + verify_connection_at_startup: + type: boolean + required: + - servers + type: object + gcs: + properties: + acl: + type: string + auto_create_bucket: + type: boolean + bucket: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_retries: + type: integer + client_timeout: + type: integer + credentials_json: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + encryption_key: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hex_random_length: + type: integer + keyfile: + type: string + object_key_format: + type: string + object_metadata: + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + overwrite: + type: boolean + path: + type: string + project: + type: string + slow_flush_log_threshold: + type: string + storage_class: + type: string + store_as: + type: string + transcoding: + type: boolean + required: + - bucket + - project + type: object + gelf: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + host: + type: string + port: + type: integer + protocol: + type: string + tls: + type: boolean + tls_options: + additionalProperties: + type: string + type: object + required: + - host + - port + type: object + http: + properties: + auth: + properties: + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - password + - username + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + content_type: + type: string + endpoint: + type: string + error_response_as_unrecoverable: + type: boolean + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + headers: + additionalProperties: + type: string + type: object + http_method: + type: string + json_array: + type: boolean + open_timeout: + type: integer + proxy: + type: string + read_timeout: + type: integer + retryable_response_codes: + items: + type: integer + type: array + slow_flush_log_threshold: + type: string + ssl_timeout: + type: integer + tls_ca_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_ciphers: + type: string + tls_client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + tls_verify_mode: + type: string + tls_version: + type: string + required: + - endpoint + type: object + kafka: + properties: + ack_timeout: + type: integer + brokers: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_id: + type: string + compression_codec: + type: string + default_message_key: + type: string + default_partition_key: + type: string + default_topic: + type: string + discard_kafka_delivery_failed: + type: boolean + exclude_partion_key: + type: boolean + exclude_topic_key: + type: boolean + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + get_kafka_client_log: + type: boolean + headers: + additionalProperties: + type: string + type: object + headers_from_record: + additionalProperties: + type: string + type: object + idempotent: + type: boolean + kafka_agg_max_bytes: + type: integer + kafka_agg_max_messages: + type: integer + keytab: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + max_send_retries: + type: integer + message_key_key: + type: string + partition_key: + type: string + partition_key_key: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + principal: + type: string + required_acks: + type: integer + sasl_over_ssl: + type: boolean + scram_mechanism: + type: string + slow_flush_log_threshold: + type: string + ssl_ca_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_ca_certs_from_system: + type: boolean + ssl_client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_client_cert_chain: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_client_cert_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ssl_verify_hostname: + type: boolean + topic_key: + type: string + use_default_for_unknown_topic: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - brokers + - format + type: object + kinesisFirehose: + properties: + append_new_line: + type: boolean + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + aws_iam_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_ses_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch_request_max_count: + type: integer + batch_request_max_size: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + delivery_stream_name: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + process_credentials: + properties: + process: + type: string + required: + - process + type: object + region: + type: string + reset_backoff_if_success: + type: boolean + retries_on_batch_request: + type: integer + slow_flush_log_threshold: + type: string + required: + - delivery_stream_name + type: object + kinesisStream: + properties: + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + aws_iam_retries: + type: integer + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_ses_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch_request_max_count: + type: integer + batch_request_max_size: + type: integer + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + partition_key: + type: string + process_credentials: + properties: + process: + type: string + required: + - process + type: object + region: + type: string + reset_backoff_if_success: + type: boolean + retries_on_batch_request: + type: integer + slow_flush_log_threshold: + type: string + stream_name: + type: string + required: + - stream_name + type: object + logdna: + properties: + api_key: + type: string + app: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + hostname: + type: string + ingester_domain: + type: string + ingester_endpoint: + type: string + request_timeout: + type: string + slow_flush_log_threshold: + type: string + tags: + type: string + required: + - api_key + - hostname + type: object + loggingRef: + type: string + logz: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_limit: + type: integer + bulk_limit_warning_limit: + type: integer + endpoint: + properties: + port: + type: integer + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + type: object + gzip: + type: boolean + http_idle_timeout: + type: integer + output_include_tags: + type: boolean + output_include_time: + type: boolean + retry_count: + type: integer + retry_sleep: + type: integer + slow_flush_log_threshold: + type: string + required: + - endpoint + type: object + loki: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + configure_kubernetes_labels: + type: boolean + drop_single_key: + type: boolean + extra_labels: + additionalProperties: + type: string + type: object + extract_kubernetes_labels: + type: boolean + include_thread_label: + type: boolean + insecure_tls: + type: boolean + key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + labels: + additionalProperties: + type: string + type: object + line_format: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + remove_keys: + items: + type: string + type: array + slow_flush_log_threshold: + type: string + tenant: + type: string + url: + type: string + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + mattermost: + properties: + ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + channel_id: + type: string + enable_tls: + type: boolean + message: + type: string + message_color: + type: string + message_title: + type: string + webhook_url: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - webhook_url + type: object + newrelic: + properties: + api_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + base_uri: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + license_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + nullout: + type: object + opensearch: + properties: + application_name: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + bulk_message_request_threshold: + type: string + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + catch_transport_exception_on_retry: + type: boolean + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key_pass: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + compression_level: + type: string + custom_headers: + type: string + customize_template: + type: string + data_stream_enable: + type: boolean + data_stream_name: + type: string + data_stream_template_name: + type: string + default_opensearch_version: + type: integer + emit_error_for_missing_id: + type: boolean + emit_error_label_event: + type: boolean + endpoint: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_arn: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_session_name: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + assume_role_web_identity_token_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ecs_container_credentials_relative_uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + region: + type: string + secret_access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + sts_credentials_region: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + required: + - url + type: object + exception_backup: + type: boolean + fail_on_detecting_os_version_retry_exceed: + type: boolean + fail_on_putting_template_retry_exceed: + type: boolean + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + hosts: + type: string + http_backend: + type: string + http_backend_excon_nonblock: + type: boolean + id_key: + type: string + ignore_exceptions: + type: string + include_index_in_url: + type: boolean + include_tag_key: + type: boolean + include_timestamp: + type: boolean + index_date_pattern: + type: string + index_name: + type: string + index_separator: + type: string + log_os_400_reason: + type: boolean + logstash_dateformat: + type: string + logstash_format: + type: boolean + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + max_retry_get_os_version: + type: integer + max_retry_putting_template: + type: string + parent_key: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + pipeline: + type: string + port: + type: integer + prefer_oj_serializer: + type: boolean + reconnect_on_error: + type: boolean + reload_after: + type: string + reload_connections: + type: boolean + reload_on_failure: + type: boolean + remove_keys_on_update: + type: string + remove_keys_on_update_key: + type: string + request_timeout: + type: string + resurrect_after: + type: string + retry_tag: + type: string + routing_key: + type: string + scheme: + type: string + selector_class_name: + type: string + slow_flush_log_threshold: + type: string + sniffer_class_name: + type: string + ssl_verify: + type: boolean + ssl_version: + type: string + suppress_doc_wrap: + type: boolean + suppress_type_name: + type: boolean + tag_key: + type: string + target_index_affinity: + type: boolean + target_index_key: + type: string + template_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + template_name: + type: string + template_overwrite: + type: boolean + templates: + type: string + time_key: + type: string + time_key_exclude_timestamp: + type: boolean + time_key_format: + type: string + time_parse_error_tag: + type: string + time_precision: + type: string + truncate_caches_interval: + type: string + unrecoverable_error_types: + type: string + unrecoverable_record_types: + type: string + use_legacy_template: + type: boolean + user: + type: string + utc_index: + type: boolean + validate_client_version: + type: boolean + verify_os_version_at_startup: + type: boolean + with_transporter_log: + type: boolean + write_operation: + type: string + type: object + oss: + properties: + access_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + access_key_secret: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + auto_create_bucket: + type: boolean + bucket: + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + check_bucket: + type: boolean + check_object: + type: boolean + download_crc_enable: + type: boolean + endpoint: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hex_random_length: + type: integer + index_format: + type: string + key_format: + type: string + open_timeout: + type: integer + oss_sdk_log_dir: + type: string + overwrite: + type: boolean + path: + type: string + read_timeout: + type: integer + slow_flush_log_threshold: + type: string + store_as: + type: string + upload_crc_enable: + type: boolean + warn_for_delay: + type: string + required: + - access_key_id + - access_key_secret + - bucket + - endpoint + type: object + redis: + properties: + allow_duplicate_key: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + db_number: + type: integer + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + host: + type: string + insert_key_prefix: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + type: integer + slow_flush_log_threshold: + type: string + strftime_format: + type: string + ttl: + type: integer + type: object + relabel: + properties: + label: + type: string + required: + - label + type: object + s3: + properties: + acl: + type: string + assume_role_credentials: + properties: + duration_seconds: + type: string + external_id: + type: string + policy: + type: string + role_arn: + type: string + role_session_name: + type: string + required: + - role_arn + - role_session_name + type: object + auto_create_bucket: + type: string + aws_iam_retries: + type: string + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + check_apikey_on_start: + type: string + check_bucket: + type: string + check_object: + type: string + clustername: + type: string + compress: + properties: + parquet_compression_codec: + type: string + parquet_page_size: + type: string + parquet_row_group_size: + type: string + record_type: + type: string + schema_file: + type: string + schema_type: + type: string + type: object + compute_checksums: + type: string + enable_transfer_acceleration: + type: string + force_path_style: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + grant_full_control: + type: string + grant_read: + type: string + grant_read_acp: + type: string + grant_write_acp: + type: string + hex_random_length: + type: string + index_format: + type: string + instance_profile_credentials: + properties: + http_open_timeout: + type: string + http_read_timeout: + type: string + ip_address: + type: string + port: + type: string + retries: + type: string + type: object + oneeye_format: + type: boolean + overwrite: + type: string + path: + type: string + proxy_uri: + type: string + s3_bucket: + type: string + s3_endpoint: + type: string + s3_metadata: + type: string + s3_object_key_format: + type: string + s3_region: + type: string + shared_credentials: + properties: + path: + type: string + profile_name: + type: string + type: object + signature_version: + type: string + slow_flush_log_threshold: + type: string + sse_customer_algorithm: + type: string + sse_customer_key: + type: string + sse_customer_key_md5: + type: string + ssekms_key_id: + type: string + ssl_verify_peer: + type: string + storage_class: + type: string + store_as: + type: string + use_bundled_cert: + type: string + use_server_side_encryption: + type: string + warn_for_delay: + type: string + required: + - s3_bucket + type: object + splunkHec: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_cert: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + client_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + coerce_to_utf8: + type: boolean + data_type: + type: string + fields: + additionalProperties: + type: string + type: object + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + hec_host: + type: string + hec_port: + type: integer + hec_token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + host: + type: string + host_key: + type: string + idle_timeout: + type: integer + index: + type: string + index_key: + type: string + insecure_ssl: + type: boolean + keep_keys: + type: boolean + metric_name_key: + type: string + metric_value_key: + type: string + metrics_from_event: + type: boolean + non_utf8_replacement_string: + type: string + open_timeout: + type: integer + protocol: + type: string + read_timeout: + type: integer + slow_flush_log_threshold: + type: string + source: + type: string + source_key: + type: string + sourcetype: + type: string + sourcetype_key: + type: string + ssl_ciphers: + type: string + required: + - hec_host + - hec_token + type: object + sqs: + properties: + aws_key_id: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + aws_sec_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + create_queue: + type: boolean + delay_seconds: + type: integer + include_tag: + type: boolean + message_group_id: + type: string + queue_name: + type: string + region: + type: string + slow_flush_log_threshold: + type: string + sqs_url: + type: string + tag_property_name: + type: string + type: object + sumologic: + properties: + add_timestamp: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + compress: + type: boolean + compress_encoding: + type: string + custom_dimensions: + type: string + custom_fields: + items: + type: string + type: array + data_type: + type: string + delimiter: + type: string + disable_cookies: + type: boolean + endpoint: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + log_format: + type: string + log_key: + type: string + metric_data_format: + type: string + open_timeout: + type: integer + proxy_uri: + type: string + slow_flush_log_threshold: + type: string + source_category: + type: string + source_host: + type: string + source_name: + type: string + source_name_key: + type: string + sumo_client: + type: string + timestamp_key: + type: string + verify_ssl: + type: boolean + required: + - endpoint + - source_name + type: object + syslog: + properties: + allow_self_signed_cert: + type: boolean + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + client_cert_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + enable_system_cert_store: + type: boolean + format: + properties: + app_name_field: + type: string + hostname_field: + type: string + log_field: + type: string + message_id_field: + type: string + proc_id_field: + type: string + rfc6587_message_size: + type: boolean + structured_data_field: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + fqdn: + type: string + host: + type: string + insecure: + type: boolean + port: + type: integer + private_key_passphrase: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + private_key_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + slow_flush_log_threshold: + type: string + transport: + type: string + trusted_ca_path: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + verify_fqdn: + type: boolean + version: + type: string + required: + - host + type: object + vmwareLogInsight: + properties: + agent_id: + type: string + authentication: + enum: + - nil + - basic + type: string + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + config_param: + additionalProperties: + type: string + type: object + flatten_hashes: + type: boolean + flatten_hashes_separator: + type: string + host: + type: string + http_conn_debug: + type: boolean + http_method: + enum: + - post + type: string + log_text_keys: + items: + type: string + type: array + max_batch_size: + type: integer + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + path: + type: string + port: + type: integer + raise_on_error: + type: boolean + rate_limit_msec: + type: integer + request_retries: + type: integer + request_timeout: + type: integer + scheme: + enum: + - http + - https + type: string + serializer: + enum: + - json + type: string + shorten_keys: + additionalProperties: + type: string + type: object + ssl_verify: + type: boolean + username: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + vmwareLogIntelligence: + properties: + buffer: + properties: + chunk_full_threshold: + type: string + chunk_limit_records: + type: integer + chunk_limit_size: + type: string + compress: + type: string + delayed_commit_timeout: + type: string + disable_chunk_backup: + type: boolean + disabled: + type: boolean + flush_at_shutdown: + type: boolean + flush_interval: + type: string + flush_mode: + type: string + flush_thread_burst_interval: + type: string + flush_thread_count: + type: integer + flush_thread_interval: + type: string + overflow_action: + type: string + path: + type: string + queue_limit_length: + type: integer + queued_chunks_limit_size: + type: integer + retry_exponential_backoff_base: + type: string + retry_forever: + type: boolean + retry_max_interval: + type: string + retry_max_times: + type: integer + retry_randomize: + type: boolean + retry_secondary_threshold: + type: string + retry_timeout: + type: string + retry_type: + type: string + retry_wait: + type: string + tags: + type: string + timekey: + type: string + timekey_use_utc: + type: boolean + timekey_wait: + type: string + timekey_zone: + type: string + total_limit_size: + type: string + type: + type: string + type: object + endpoint_url: + type: string + format: + properties: + add_newline: + type: boolean + message_key: + type: string + type: + enum: + - out_file + - json + - ltsv + - csv + - msgpack + - hash + - single_value + type: string + type: object + headers: + properties: + authorization: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + content_type: + type: string + structure: + type: string + required: + - authorization + - content_type + - structure + type: object + http_compress: + type: boolean + verify_ssl: + type: boolean + required: + - endpoint_url + - headers + - verify_ssl + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngclusterflows.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngclusterflows.yaml new file mode 100644 index 0000000000..51534c3ed5 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngclusterflows.yaml @@ -0,0 +1,360 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: syslogngclusterflows.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: SyslogNGClusterFlow + listKind: SyslogNGClusterFlowList + plural: syslogngclusterflows + singular: syslogngclusterflow + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the flow active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + filters: + items: + properties: + id: + type: string + match: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + parser: + properties: + metrics-probe: + properties: + key: + type: string + labels: + additionalProperties: + type: string + type: object + level: + type: integer + type: object + regexp: + properties: + flags: + items: + type: string + type: array + patterns: + items: + type: string + type: array + prefix: + type: string + template: + type: string + required: + - patterns + type: object + syslog-parser: + properties: + flags: + items: + type: string + type: array + type: object + type: object + rewrite: + items: + properties: + group_unset: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + pattern: + type: string + required: + - pattern + type: object + rename: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + newName: + type: string + oldName: + type: string + required: + - newName + - oldName + type: object + set: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + field: + type: string + value: + type: string + required: + - field + - value + type: object + subst: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + field: + type: string + flags: + items: + type: string + type: array + pattern: + type: string + replace: + type: string + type: + type: string + required: + - field + - pattern + - replace + type: object + unset: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + field: + type: string + required: + - field + type: object + type: object + type: array + type: object + type: array + globalOutputRefs: + items: + type: string + type: array + loggingRef: + type: string + match: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + outputMetrics: + items: + properties: + key: + type: string + labels: + additionalProperties: + type: string + type: object + level: + type: integer + type: object + type: array + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngclusteroutputs.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngclusteroutputs.yaml new file mode 100644 index 0000000000..7227853901 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngclusteroutputs.yaml @@ -0,0 +1,2911 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: syslogngclusteroutputs.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: SyslogNGClusterOutput + listKind: SyslogNGClusterOutputList + plural: syslogngclusteroutputs + singular: syslogngclusteroutput + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the output active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + elasticsearch: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + body-prefix: + type: string + body-suffix: + type: string + custom_id: + type: string + delimiter: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + headers: + items: + type: string + type: array + index: + type: string + log-fifo-size: + type: integer + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + logstash_suffix: + type: string + method: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + persist_name: + type: string + response-action: + additionalProperties: + type: string + type: object + retries: + type: integer + template: + type: string + time_reopen: + type: integer + timeout: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + type: + type: string + url: + type: string + user: + type: string + user-agent: + type: string + workers: + type: integer + type: object + enabledNamespaces: + items: + type: string + type: array + file: + properties: + create_dirs: + type: boolean + dir_group: + type: string + dir_owner: + type: string + dir_perm: + type: integer + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + path: + type: string + persist_name: + type: string + template: + type: string + required: + - path + type: object + http: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + body-prefix: + type: string + body-suffix: + type: string + delimiter: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + headers: + items: + type: string + type: array + log-fifo-size: + type: integer + method: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + persist_name: + type: string + response-action: + additionalProperties: + type: string + type: object + retries: + type: integer + time_reopen: + type: integer + timeout: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + url: + type: string + user: + type: string + user-agent: + type: string + workers: + type: integer + type: object + loggingRef: + type: string + loggly: + properties: + close_on_input: + type: boolean + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + flags: + items: + type: string + type: array + flush_lines: + type: integer + host: + type: string + persist_name: + type: string + port: + type: integer + so_keepalive: + type: boolean + suppress: + type: integer + tag: + type: string + template: + type: string + template_escape: + type: boolean + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + transport: + type: string + ts_format: + type: string + required: + - token + type: object + logscale: + properties: + attributes: + type: string + batch_bytes: + type: integer + batch_lines: + type: integer + batch_timeout: + type: integer + body: + type: string + content_type: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + extra_headers: + type: string + persist_name: + type: string + rawstring: + type: string + timezone: + type: string + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + loki: + properties: + auth: + properties: + adc: + type: object + alts: + properties: + target-service-accounts: + items: + type: string + type: array + type: object + insecure: + type: object + tls: + properties: + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + type: object + batch-lines: + type: integer + batch-timeout: + type: integer + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + labels: + additionalProperties: + type: string + type: object + log-fifo-size: + type: integer + persist_name: + type: string + retries: + type: integer + template: + type: string + time_reopen: + type: integer + timestamp: + enum: + - current + - received + - msg + type: string + url: + type: string + workers: + type: integer + type: object + mongodb: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + bulk: + type: boolean + bulk_bypass_validation: + type: boolean + bulk_unordered: + type: boolean + collection: + type: string + dir: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + log-fifo-size: + type: integer + persist_name: + type: string + retries: + type: integer + time_reopen: + type: integer + uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + value_pairs: + properties: + exclude: + type: string + key: + type: string + pair: + type: string + scope: + type: string + type: object + write_concern: + enum: + - unacked + - acked + - majority + type: string + required: + - collection + type: object + mqtt: + properties: + address: + type: string + fallback-topic: + type: string + qos: + type: integer + template: + type: string + topic: + type: string + type: object + openobserve: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + body-prefix: + type: string + body-suffix: + type: string + delimiter: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + headers: + items: + type: string + type: array + log-fifo-size: + type: integer + method: + type: string + organization: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + persist_name: + type: string + port: + type: integer + record: + type: string + response-action: + additionalProperties: + type: string + type: object + retries: + type: integer + stream: + type: string + time_reopen: + type: integer + timeout: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + url: + type: string + user: + type: string + user-agent: + type: string + workers: + type: integer + type: object + redis: + properties: + auth: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + command: + properties: + string-list: + items: + type: string + type: array + type: object + command_and_arguments: + items: + type: string + type: array + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + host: + type: string + log-fifo-size: + type: integer + persist_name: + type: string + port: + type: integer + retries: + type: integer + throttle: + type: integer + time-reopen: + type: integer + workers: + type: integer + type: object + s3: + properties: + access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + bucket: + type: string + canned_acl: + type: string + chunk_size: + type: integer + compression: + type: boolean + compresslevel: + type: integer + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + flush_grace_period: + type: integer + log-fifo-size: + type: integer + max_object_size: + type: integer + max_pending_uploads: + type: integer + object_key: + type: string + object_key_timestamp: + type: string + persist_name: + type: string + region: + type: string + retries: + type: integer + secret_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + storage_class: + type: string + template: + type: string + throttle: + type: integer + upload_threads: + type: integer + url: + type: string + type: object + splunk_hec_event: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + body-prefix: + type: string + body-suffix: + type: string + content_type: + type: string + default_index: + type: string + default_source: + type: string + default_sourcetype: + type: string + delimiter: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + event: + type: string + extra_headers: + items: + type: string + type: array + extra_queries: + items: + type: string + type: array + fields: + type: string + headers: + items: + type: string + type: array + host: + type: string + index: + type: string + log-fifo-size: + type: integer + method: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + persist_name: + type: string + response-action: + additionalProperties: + type: string + type: object + retries: + type: integer + source: + type: string + sourcetype: + type: string + time: + type: string + time_reopen: + type: integer + timeout: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + user: + type: string + user-agent: + type: string + workers: + type: integer + type: object + sumologic-http: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + collector: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + deployment: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + headers: + items: + type: string + type: array + persist_name: + type: string + time_reopen: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + url: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + sumologic-syslog: + properties: + deployment: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + persist_name: + type: string + port: + type: integer + tag: + type: string + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + token: + type: integer + type: object + syslog: + properties: + close_on_input: + type: boolean + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + flags: + items: + type: string + type: array + flush_lines: + type: integer + host: + type: string + persist_name: + type: string + port: + type: integer + so_keepalive: + type: boolean + suppress: + type: integer + template: + type: string + template_escape: + type: boolean + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + transport: + type: string + ts_format: + type: string + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngconfigs.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngconfigs.yaml new file mode 100644 index 0000000000..879463dd46 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngconfigs.yaml @@ -0,0 +1,8104 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: syslogngconfigs.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: SyslogNGConfig + listKind: SyslogNGConfigList + plural: syslogngconfigs + singular: syslogngconfig + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + bufferVolumeMetrics: + properties: + interval: + type: string + mount_name: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + bufferVolumeMetricsService: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + trafficDistribution: + type: string + type: + type: string + type: object + type: object + configCheck: + properties: + labels: + additionalProperties: + type: string + type: object + strategy: + type: string + timeoutSeconds: + type: integer + type: object + configCheckPod: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + globalOptions: + properties: + log_level: + type: string + stats: + properties: + freq: + type: integer + level: + type: integer + type: object + stats_freq: + type: integer + stats_level: + type: integer + type: object + jsonKeyDelim: + type: string + jsonKeyPrefix: + type: string + logIWSize: + type: integer + maxConnections: + type: integer + metrics: + properties: + interval: + type: string + path: + type: string + port: + format: int32 + type: integer + prometheusAnnotations: + type: boolean + prometheusRules: + type: boolean + serviceMonitor: + type: boolean + serviceMonitorConfig: + properties: + additionalLabels: + additionalProperties: + type: string + type: object + honorLabels: + type: boolean + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + timeout: + type: string + type: object + metricsService: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + trafficDistribution: + type: string + type: + type: string + type: object + type: object + readinessDefaultCheck: + properties: + bufferFileNumber: + type: boolean + bufferFileNumberMax: + format: int32 + type: integer + bufferFreeSpace: + type: boolean + bufferFreeSpaceThreshold: + format: int32 + type: integer + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + trafficDistribution: + type: string + type: + type: string + type: object + type: object + serviceAccount: + properties: + automountServiceAccountToken: + type: boolean + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + secrets: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + type: object + skipRBACCreate: + type: boolean + sourceDateParser: + properties: + format: + type: string + template: + type: string + type: object + sourceMetrics: + items: + properties: + key: + type: string + labels: + additionalProperties: + type: string + type: object + level: + type: integer + type: object + type: array + statefulSet: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + podManagementPolicy: + type: string + replicas: + format: int32 + type: integer + revisionHistoryLimit: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + serviceName: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + updateStrategy: + properties: + rollingUpdate: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + partition: + format: int32 + type: integer + type: object + type: + type: string + type: object + volumeClaimTemplates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: array + type: object + type: object + tls: + properties: + enabled: + type: boolean + secretName: + type: string + sharedKey: + type: string + required: + - enabled + type: object + type: object + status: + properties: + active: + type: boolean + logging: + type: string + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngflows.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngflows.yaml new file mode 100644 index 0000000000..712fa42628 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngflows.yaml @@ -0,0 +1,364 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: syslogngflows.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: SyslogNGFlow + listKind: SyslogNGFlowList + plural: syslogngflows + singular: syslogngflow + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the flow active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + filters: + items: + properties: + id: + type: string + match: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + parser: + properties: + metrics-probe: + properties: + key: + type: string + labels: + additionalProperties: + type: string + type: object + level: + type: integer + type: object + regexp: + properties: + flags: + items: + type: string + type: array + patterns: + items: + type: string + type: array + prefix: + type: string + template: + type: string + required: + - patterns + type: object + syslog-parser: + properties: + flags: + items: + type: string + type: array + type: object + type: object + rewrite: + items: + properties: + group_unset: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + pattern: + type: string + required: + - pattern + type: object + rename: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + newName: + type: string + oldName: + type: string + required: + - newName + - oldName + type: object + set: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + field: + type: string + value: + type: string + required: + - field + - value + type: object + subst: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + field: + type: string + flags: + items: + type: string + type: array + pattern: + type: string + replace: + type: string + type: + type: string + required: + - field + - pattern + - replace + type: object + unset: + properties: + condition: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + field: + type: string + required: + - field + type: object + type: object + type: array + type: object + type: array + globalOutputRefs: + items: + type: string + type: array + localOutputRefs: + items: + type: string + type: array + loggingRef: + type: string + match: + properties: + and: + x-kubernetes-preserve-unknown-fields: true + not: + x-kubernetes-preserve-unknown-fields: true + or: + x-kubernetes-preserve-unknown-fields: true + regexp: + properties: + flags: + items: + type: string + type: array + pattern: + type: string + template: + type: string + type: + type: string + value: + type: string + required: + - pattern + type: object + type: object + outputMetrics: + items: + properties: + key: + type: string + labels: + additionalProperties: + type: string + type: object + level: + type: integer + type: object + type: array + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngoutputs.yaml b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngoutputs.yaml new file mode 100644 index 0000000000..09b75d417d --- /dev/null +++ b/charts/rancher-logging-crd/104.1.1+up4.8.0/templates/logging.banzaicloud.io_syslogngoutputs.yaml @@ -0,0 +1,2905 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: syslogngoutputs.logging.banzaicloud.io +spec: + group: logging.banzaicloud.io + names: + categories: + - logging-all + kind: SyslogNGOutput + listKind: SyslogNGOutputList + plural: syslogngoutputs + singular: syslogngoutput + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Is the output active? + jsonPath: .status.active + name: Active + type: boolean + - description: Number of problems + jsonPath: .status.problemsCount + name: Problems + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + elasticsearch: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + body-prefix: + type: string + body-suffix: + type: string + custom_id: + type: string + delimiter: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + headers: + items: + type: string + type: array + index: + type: string + log-fifo-size: + type: integer + logstash_prefix: + type: string + logstash_prefix_separator: + type: string + logstash_suffix: + type: string + method: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + persist_name: + type: string + response-action: + additionalProperties: + type: string + type: object + retries: + type: integer + template: + type: string + time_reopen: + type: integer + timeout: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + type: + type: string + url: + type: string + user: + type: string + user-agent: + type: string + workers: + type: integer + type: object + file: + properties: + create_dirs: + type: boolean + dir_group: + type: string + dir_owner: + type: string + dir_perm: + type: integer + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + path: + type: string + persist_name: + type: string + template: + type: string + required: + - path + type: object + http: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + body-prefix: + type: string + body-suffix: + type: string + delimiter: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + headers: + items: + type: string + type: array + log-fifo-size: + type: integer + method: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + persist_name: + type: string + response-action: + additionalProperties: + type: string + type: object + retries: + type: integer + time_reopen: + type: integer + timeout: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + url: + type: string + user: + type: string + user-agent: + type: string + workers: + type: integer + type: object + loggingRef: + type: string + loggly: + properties: + close_on_input: + type: boolean + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + flags: + items: + type: string + type: array + flush_lines: + type: integer + host: + type: string + persist_name: + type: string + port: + type: integer + so_keepalive: + type: boolean + suppress: + type: integer + tag: + type: string + template: + type: string + template_escape: + type: boolean + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + transport: + type: string + ts_format: + type: string + required: + - token + type: object + logscale: + properties: + attributes: + type: string + batch_bytes: + type: integer + batch_lines: + type: integer + batch_timeout: + type: integer + body: + type: string + content_type: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + extra_headers: + type: string + persist_name: + type: string + rawstring: + type: string + timezone: + type: string + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + loki: + properties: + auth: + properties: + adc: + type: object + alts: + properties: + target-service-accounts: + items: + type: string + type: array + type: object + insecure: + type: object + tls: + properties: + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + type: object + batch-lines: + type: integer + batch-timeout: + type: integer + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + labels: + additionalProperties: + type: string + type: object + log-fifo-size: + type: integer + persist_name: + type: string + retries: + type: integer + template: + type: string + time_reopen: + type: integer + timestamp: + enum: + - current + - received + - msg + type: string + url: + type: string + workers: + type: integer + type: object + mongodb: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + bulk: + type: boolean + bulk_bypass_validation: + type: boolean + bulk_unordered: + type: boolean + collection: + type: string + dir: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + log-fifo-size: + type: integer + persist_name: + type: string + retries: + type: integer + time_reopen: + type: integer + uri: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + value_pairs: + properties: + exclude: + type: string + key: + type: string + pair: + type: string + scope: + type: string + type: object + write_concern: + enum: + - unacked + - acked + - majority + type: string + required: + - collection + type: object + mqtt: + properties: + address: + type: string + fallback-topic: + type: string + qos: + type: integer + template: + type: string + topic: + type: string + type: object + openobserve: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + body-prefix: + type: string + body-suffix: + type: string + delimiter: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + headers: + items: + type: string + type: array + log-fifo-size: + type: integer + method: + type: string + organization: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + persist_name: + type: string + port: + type: integer + record: + type: string + response-action: + additionalProperties: + type: string + type: object + retries: + type: integer + stream: + type: string + time_reopen: + type: integer + timeout: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + url: + type: string + user: + type: string + user-agent: + type: string + workers: + type: integer + type: object + redis: + properties: + auth: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + command: + properties: + string-list: + items: + type: string + type: array + type: object + command_and_arguments: + items: + type: string + type: array + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + host: + type: string + log-fifo-size: + type: integer + persist_name: + type: string + port: + type: integer + retries: + type: integer + throttle: + type: integer + time-reopen: + type: integer + workers: + type: integer + type: object + s3: + properties: + access_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + bucket: + type: string + canned_acl: + type: string + chunk_size: + type: integer + compression: + type: boolean + compresslevel: + type: integer + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + flush_grace_period: + type: integer + log-fifo-size: + type: integer + max_object_size: + type: integer + max_pending_uploads: + type: integer + object_key: + type: string + object_key_timestamp: + type: string + persist_name: + type: string + region: + type: string + retries: + type: integer + secret_key: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + storage_class: + type: string + template: + type: string + throttle: + type: integer + upload_threads: + type: integer + url: + type: string + type: object + splunk_hec_event: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + body-prefix: + type: string + body-suffix: + type: string + content_type: + type: string + default_index: + type: string + default_source: + type: string + default_sourcetype: + type: string + delimiter: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + event: + type: string + extra_headers: + items: + type: string + type: array + extra_queries: + items: + type: string + type: array + fields: + type: string + headers: + items: + type: string + type: array + host: + type: string + index: + type: string + log-fifo-size: + type: integer + method: + type: string + password: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + persist_name: + type: string + response-action: + additionalProperties: + type: string + type: object + retries: + type: integer + source: + type: string + sourcetype: + type: string + time: + type: string + time_reopen: + type: integer + timeout: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + token: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + url: + type: string + user: + type: string + user-agent: + type: string + workers: + type: integer + type: object + sumologic-http: + properties: + batch-bytes: + type: integer + batch-lines: + type: integer + batch-timeout: + type: integer + body: + type: string + collector: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + deployment: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + headers: + items: + type: string + type: array + persist_name: + type: string + time_reopen: + type: integer + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + url: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + sumologic-syslog: + properties: + deployment: + type: string + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + persist_name: + type: string + port: + type: integer + tag: + type: string + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + token: + type: integer + type: object + syslog: + properties: + close_on_input: + type: boolean + disk_buffer: + properties: + compaction: + type: boolean + dir: + type: string + disk_buf_size: + format: int64 + type: integer + mem_buf_length: + format: int64 + type: integer + mem_buf_size: + format: int64 + type: integer + q_out_size: + format: int64 + type: integer + reliable: + type: boolean + required: + - disk_buf_size + - reliable + type: object + flags: + items: + type: string + type: array + flush_lines: + type: integer + host: + type: string + persist_name: + type: string + port: + type: integer + so_keepalive: + type: boolean + suppress: + type: integer + template: + type: string + template_escape: + type: boolean + tls: + properties: + ca_dir: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + ca_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cert_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + cipher-suite: + type: string + key_file: + properties: + mountFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + value: + type: string + valueFrom: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + peer_verify: + type: boolean + ssl_version: + enum: + - sslv3 + - tlsv1 + - tlsv1_0 + - tlsv1_1 + - tlsv1_2 + - tlsv1_3 + type: string + use-system-cert-store: + type: boolean + type: object + transport: + type: string + ts_format: + type: string + type: object + type: object + status: + properties: + active: + type: boolean + problems: + items: + type: string + type: array + problemsCount: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/.helmignore b/charts/rancher-logging/104.1.1+up4.8.0/.helmignore new file mode 100644 index 0000000000..b3123b9ea0 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/.helmignore @@ -0,0 +1,26 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +ci/ +README.md.gotmpl diff --git a/charts/rancher-logging/104.1.1+up4.8.0/Chart.yaml b/charts/rancher-logging/104.1.1+up4.8.0/Chart.yaml new file mode 100644 index 0000000000..59624d568a --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/Chart.yaml @@ -0,0 +1,30 @@ +annotations: + catalog.cattle.io/auto-install: rancher-logging-crd=match + catalog.cattle.io/certified: rancher + catalog.cattle.io/deploys-on-os: windows + catalog.cattle.io/display-name: Logging + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.0-0' + catalog.cattle.io/namespace: cattle-logging-system + catalog.cattle.io/permits-os: linux,windows + catalog.cattle.io/provides-gvr: logging.banzaicloud.io.clusterflow/v1beta1 + catalog.cattle.io/rancher-version: '>= 2.9.0-0 < 2.10.0-0' + catalog.cattle.io/release-name: rancher-logging + catalog.cattle.io/type: cluster-tool + catalog.cattle.io/ui-component: logging + catalog.cattle.io/upstream-version: 4.8.0 +apiVersion: v2 +appVersion: 4.8.0 +description: Logging operator for Kubernetes based on Fluentd and Fluentbit. +home: https://kube-logging.github.io +icon: file://assets/logos/rancher-logging.svg +keywords: +- logging +- fluentd +- fluentbit +kubeVersion: '>=1.26.0-0' +name: rancher-logging +sources: +- https://github.com/kube-logging/logging-operator +- https://github.com/kube-logging/helm-charts/tree/main/charts/logging-operator +type: application +version: 104.1.1+up4.8.0 diff --git a/charts/rancher-logging/104.1.1+up4.8.0/README.md b/charts/rancher-logging/104.1.1+up4.8.0/README.md new file mode 100644 index 0000000000..7f66f42ab6 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/README.md @@ -0,0 +1,134 @@ +# logging-operator + +![type: application](https://img.shields.io/badge/type-application-informational?style=flat-square) ![kube version: >=1.22.0-0](https://img.shields.io/badge/kube%20version->=1.22.0--0-informational?style=flat-square) [![artifact hub](https://img.shields.io/badge/artifact%20hub-logging--operator-informational?style=flat-square)](https://artifacthub.io/packages/helm/kube-logging/logging-operator) + +Logging operator for Kubernetes based on Fluentd and Fluentbit. + +**Homepage:** + +## TL;DR; + +```bash +helm install --generate-name --wait oci://ghcr.io/kube-logging/helm-charts/logging-operator +``` + +or to install with a specific version: + +```bash +helm install --generate-name --wait oci://ghcr.io/kube-logging/helm-charts/logging-operator --version $VERSION +``` + +## Introduction + +This chart bootstraps a [Logging Operator](https://github.com/kube-logging/logging-operator) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes 1.19+ + +## Installing CRDs + +Use `createCustomResource=false` with Helm v3 to avoid trying to create CRDs from the `crds` folder and from templates at the same time. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| replicaCount | int | `1` | | +| image.repository | string | `"ghcr.io/kube-logging/logging-operator"` | Name of the image repository to pull the container image from. | +| image.tag | string | `""` | Image tag override for the default value (chart appVersion). | +| image.pullPolicy | string | `"IfNotPresent"` | [Image pull policy](https://kubernetes.io/docs/concepts/containers/images/#updating-images) for updating already existing images on a node. | +| env | list | `[]` | | +| volumes | list | `[]` | | +| volumeMounts | list | `[]` | | +| extraArgs[0] | string | `"-enable-leader-election=true"` | | +| imagePullSecrets | list | `[]` | | +| nameOverride | string | `""` | A name in place of the chart name for `app:` labels. | +| fullnameOverride | string | `""` | A name to substitute for the full names of resources. | +| namespaceOverride | string | `""` | A namespace override for the app. | +| annotations | object | `{}` | Define annotations for logging-operator pods. | +| createCustomResource | bool | `false` | Deploy CRDs used by Logging Operator. | +| http.port | int | `8080` | HTTP listen port number. | +| http.service | object | `{"annotations":{},"clusterIP":"None","labels":{},"type":"ClusterIP"}` | Service definition for query http service. | +| rbac.enabled | bool | `true` | Create rbac service account and roles. | +| monitoring.serviceMonitor.enabled | bool | `false` | Create a Prometheus Operator ServiceMonitor object. | +| monitoring.serviceMonitor.additionalLabels | object | `{}` | | +| monitoring.serviceMonitor.metricRelabelings | list | `[]` | | +| monitoring.serviceMonitor.relabelings | list | `[]` | | +| podSecurityContext | object | `{}` | Pod SecurityContext for Logging operator. [More info](https://kubernetes.io/docs/concepts/policy/security-context/) # 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 | object | `{}` | Container SecurityContext for Logging operator. [More info](https://kubernetes.io/docs/concepts/policy/security-context/) | +| priorityClassName | object | `{}` | Operator priorityClassName. | +| serviceAccount.annotations | object | `{}` | Define annotations for logging-operator ServiceAccount. | +| resources | object | `{}` | CPU/Memory resource requests/limits | +| nodeSelector | object | `{}` | | +| tolerations | list | `[]` | Node Tolerations | +| affinity | object | `{}` | Node Affinity | +| podLabels | object | `{}` | Define which Nodes the Pods are scheduled on. | +| logging | object | `{"allowClusterResourcesFromAllNamespaces":false,"clusterDomain":"cluster.local.","clusterFlows":[],"clusterOutputs":[],"controlNamespace":"","defaultFlow":{},"enableRecreateWorkloadOnImmutableFieldChange":false,"enabled":false,"errorOutputRef":"","eventTailer":{},"flowConfigCheckDisabled":false,"flowConfigOverride":"","fluentbit":{},"fluentbitDisabled":false,"fluentd":{},"fluentdDisabled":false,"globalFilters":[],"hostTailer":{},"loggingRef":"","nodeAgents":{},"skipInvalidResources":false,"syslogNG":{},"watchNamespaceSelector":{},"watchNamespaces":[]}` | Logging resources configuration. | +| logging.enabled | bool | `false` | Logging resources are disabled by default | +| logging.loggingRef | string | `""` | Reference to the logging system. Each of the loggingRefs can manage a fluentbit daemonset and a fluentd statefulset. | +| logging.flowConfigCheckDisabled | bool | `false` | Disable configuration check before applying new fluentd configuration. | +| logging.skipInvalidResources | bool | `false` | Whether to skip invalid Flow and ClusterFlow resources | +| logging.flowConfigOverride | string | `""` | Override generated config. This is a raw configuration string for troubleshooting purposes. | +| logging.fluentbitDisabled | bool | `false` | Flag to disable fluentbit completely | +| logging.fluentbit | object | `{}` | Fluent-bit configurations https://kube-logging.github.io/docs/configuration/crds/v1beta1/fluentbit_types/ | +| logging.fluentdDisabled | bool | `false` | Flag to disable fluentd completely | +| logging.fluentd | object | `{}` | Fluentd configurations https://kube-logging.github.io/docs/configuration/crds/v1beta1/fluentd_types/ | +| logging.syslogNG | object | `{}` | Syslog-NG statefulset configuration | +| logging.defaultFlow | object | `{}` | Default flow for unmatched logs. This Flow configuration collects all logs that didn’t match any other Flow. | +| logging.errorOutputRef | string | `""` | GlobalOutput name to flush ERROR events to | +| logging.globalFilters | list | `[]` | Global filters to apply on logs before any match or filter mechanism. | +| logging.watchNamespaces | list | `[]` | Limit namespaces to watch Flow and Output custom resources. | +| logging.watchNamespaceSelector | object | `{}` | Limit namespaces to watch Flow and Output custom resources. | +| logging.clusterDomain | string | `"cluster.local."` | Cluster domain name to be used when templating URLs to services | +| logging.controlNamespace | string | `""` | Namespace for cluster wide configuration resources like ClusterFlow and ClusterOutput. This should be a protected namespace from regular users. Resources like fluentbit and fluentd will run in this namespace as well. | +| logging.allowClusterResourcesFromAllNamespaces | bool | `false` | Allow configuration of cluster resources from any namespace. Mutually exclusive with ControlNamespace restriction of Cluster resources | +| logging.nodeAgents | object | `{}` | NodeAgent Configuration | +| logging.configCheck | object | `{}` | configCheck provides possibility for timeout-based configuration checks https://kube-logging.dev/docs/whats-new/#timeout-based-configuration-checks | +| logging.enableRecreateWorkloadOnImmutableFieldChange | bool | `false` | EnableRecreateWorkloadOnImmutableFieldChange enables the operator to recreate the fluentbit daemonset and the fluentd statefulset (and possibly other resource in the future) in case there is a change in an immutable field that otherwise couldn’t be managed with a simple update. | +| logging.clusterFlows | list | `[]` | ClusterFlows to deploy | +| logging.clusterOutputs | list | `[]` | ClusterOutputs to deploy | +| logging.eventTailer.enabled | bool | `false` | | +| logging.eventTailer.name | string | `"event-tailer"` | | +| logging.eventTailer.image.repository | string | `nil` | repository of eventTailer image | +| logging.eventTailer.image.tag | string | `nil` | tag of eventTailer image | +| logging.eventTailer.image.pullPolicy | string | `nil` | pullPolicy of eventTailer image | +| logging.eventTailer.image.imagePullSecrets | list | `[]` | imagePullSecrets of eventTailer image | +| logging.eventTailer.pvc.enabled | bool | `true` | enable pvc for | +| logging.eventTailer.pvc.accessModes | list | `["ReadWriteOnce"]` | storage class for event tailer pvc | +| logging.eventTailer.pvc.volumeMode | string | `"Filesystem"` | storage class for event tailer pvc | +| logging.eventTailer.pvc.storage | string | `"1Gi"` | storage for event tailer pvc | +| logging.eventTailer.pvc.storageClassName | string | `nil` | storage class for event tailer pvc | +| logging.eventTailer.workloadMetaOverrides | string | `nil` | workloadMetaOverrides | +| logging.eventTailer.workloadOverrides | string | `nil` | workloadOverrides | +| logging.eventTailer.containerOverrides | string | `nil` | containerOverrides | +| logging.hostTailer.enabled | bool | `false` | HostTailer | +| logging.hostTailer.name | string | `"hosttailer"` | name of HostTailer | +| logging.hostTailer.image.repository | string | `nil` | repository of eventTailer image | +| logging.hostTailer.image.tag | string | `nil` | tag of eventTailer image | +| logging.hostTailer.image.pullPolicy | string | `nil` | pullPolicy of eventTailer image | +| logging.hostTailer.image.imagePullSecrets | list | `[]` | imagePullSecrets of eventTailer image | +| logging.hostTailer.workloadMetaOverrides | string | `nil` | workloadMetaOverrides of HostTailer | +| logging.hostTailer.workloadOverrides | string | `nil` | workloadOverrides of HostTailer | +| logging.hostTailer.fileTailers | list | `[]` | configure fileTailers of HostTailer example: - name: sample-file path: /var/log/sample-file disabled: false buffer_max_size: buffer_chunk_size: skip_long_lines: read_from_head: false containerOverrides: image: | +| logging.hostTailer.systemdTailers | list | `[]` | configure systemdTailers of HostTailer example: - name: system-sample disabled: false systemdFilter: kubelet.service maxEntries: 20 containerOverrides: image: | +| testReceiver.enabled | bool | `false` | | +| testReceiver.image | string | `"fluent/fluent-bit"` | | +| testReceiver.pullPolicy | string | `"IfNotPresent"` | | +| testReceiver.port | int | `8080` | | +| testReceiver.args[0] | string | `"-i"` | | +| testReceiver.args[1] | string | `"http"` | | +| testReceiver.args[2] | string | `"-p"` | | +| testReceiver.args[3] | string | `"port=8080"` | | +| testReceiver.args[4] | string | `"-o"` | | +| testReceiver.args[5] | string | `"stdout"` | | +| testReceiver.resources.limits.cpu | string | `"100m"` | | +| testReceiver.resources.limits.memory | string | `"50Mi"` | | +| testReceiver.resources.requests.cpu | string | `"20m"` | | +| testReceiver.resources.requests.memory | string | `"25Mi"` | | +| extraManifests | list | `[]` | Extra manifests to deploy as an array | + +## Installing Fluentd and Fluent-bit via logging + +The chart does **not** install `logging` resource to deploy Fluentd (or Syslog-ng) and Fluent-bit on the cluster by default, but +it can be enabled by setting the `logging.enabled` value to true. diff --git a/charts/rancher-logging/104.1.1+up4.8.0/app-readme.md b/charts/rancher-logging/104.1.1+up4.8.0/app-readme.md new file mode 100644 index 0000000000..994c597ee5 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/app-readme.md @@ -0,0 +1,45 @@ +# Rancher Logging + +This chart is based off of the upstream [Banzai Logging Operator](https://banzaicloud.com/docs/one-eye/logging-operator/) chart. The chart deploys a logging operator and CRDs, which allows users to configure complex logging pipelines with a few simple custom resources. There are two levels of logging, which allow you to collect all logs in a cluster or from a single namespace. + +For more information on how to use the feature, refer to our [docs](https://rancher.com/docs/rancher/v2.x/en/logging/v2.7/). + +## 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. + +## Namespace-level logging + +To collect logs from a single namespace, users create flows and these flows are connected to outputs or cluster outputs. + +## Cluster-level logging + +To collect logs from an entire cluster, users create cluster flows and cluster outputs. + +## CRDs + +- [Cluster Flow](https://banzaicloud.com/docs/one-eye/logging-operator/crds/v1beta1/clusterflow_types/) - A cluster flow is a CRD (`ClusterFlow`) that defines what logs to collect from the entire cluster. The cluster flow must be deployed in the same namespace as the logging operator. +- [Cluster Output](https://banzaicloud.com/docs/one-eye/logging-operator/crds/v1beta1/clusteroutput_types/) - A cluster output is a CRD (`ClusterOutput`) that defines how to connect to logging providers so they can start collecting logs. The cluster output must be deployed in the same namespace as the logging operator. The convenience of using a cluster output is that either a cluster flow or flow can send logs to those providers without needing to define specific outputs in each namespace for each flow. +- [Flow](https://banzaicloud.com/docs/one-eye/logging-operator/crds/v1beta1/flow_types/) - A flow is a CRD (`Flow`) that defines what logs to collect from the namespace that it is deployed in. +- [Output](https://banzaicloud.com/docs/one-eye/logging-operator/crds/v1beta1/output_types/) - An output is a CRD (`Output`) that defines how to connect to logging providers so logs can be sent to the provider. + +For more information on how to configure the Helm chart, refer to the Helm README. + +## Systemd Configuration +Some Kubernetes distributions log to journald. In order to collect these logs the `systemdLogPath` needs to be defined. While the `/run/log/journal` directory is used by default, some Linux distributions do not default to this path. For example Ubuntu defaults to `/var/log/journal`. To determine your `systemdLogPath` run `cat /etc/systemd/journald.conf | grep -E ^\#?Storage | cut -d"=" -f2` on one of your nodes. If `persistent` is returned your `systemdLogPath` should be `/var/log/journal`. If `volatile` is returned `systemdLogPath` should be `/run/log/journal`. If `auto` is returned check if `/var/log/journal` exists, and if it does then use `/var/log/journal`, otherwise use `/run/log/journal`. + +If any value not described here is returned, Rancher Logging will not be able to collect control plane logs. To address this issue set `Storage=volatile` in journald.conf, reboot your machine, and set `systemdLogPath` to `/run/log/journal`. diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/NOTES.txt b/charts/rancher-logging/104.1.1+up4.8.0/templates/NOTES.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/_generic_fluentbitagent.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/_generic_fluentbitagent.yaml new file mode 100644 index 0000000000..64dd0131d4 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/_generic_fluentbitagent.yaml @@ -0,0 +1,82 @@ +{{- define "logging-operator.fluentbitagent.tpl" -}} +apiVersion: logging.banzaicloud.io/v1beta1 +kind: FluentbitAgent +metadata: + namespace: {{ .Release.Namespace }} + labels: +{{ include "logging-operator.labels" . | indent 4 }} +spec: + image: + repository: {{ template "logging-operator.fluentbitImageRepository" . }} + tag: {{ template "logging-operator.fluentbitImageTag" . }} + {{- if not .Values.disablePvc }} + {{- with .Values.fluentbit.bufferStorage }} + bufferStorage: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.fluentbit.bufferStorageVolume }} + bufferStorageVolume: {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + {{- if or .Values.global.cattle.psp.enabled .Values.global.seLinux.enabled }} + security: + {{- end }} + {{- if .Values.global.cattle.psp.enabled }} + podSecurityPolicyCreate: true + roleBasedAccessControlCreate: true + {{- end }} + {{- if .Values.global.seLinux.enabled }} + securityContext: + seLinuxOptions: + type: rke_logreader_t + {{- end }} + {{- if or .Values.fluentbit.inputTail.Buffer_Chunk_Size .Values.fluentbit.inputTail.Buffer_Max_Size .Values.fluentbit.inputTail.Mem_Buf_Limit .Values.fluentbit.inputTail.Multiline_Flush .Values.fluentbit.inputTail.Skip_Long_Lines }} + inputTail: + {{- if .Values.fluentbit.inputTail.Buffer_Chunk_Size }} + Buffer_Chunk_Size: {{ .Values.fluentbit.inputTail.Buffer_Chunk_Size | toString }} + {{- end }} + {{- if .Values.fluentbit.inputTail.Buffer_Max_Size }} + Buffer_Max_Size: {{ .Values.fluentbit.inputTail.Buffer_Max_Size | toString }} + {{- end }} + {{- if .Values.fluentbit.inputTail.Mem_Buf_Limit }} + Mem_Buf_Limit: {{ .Values.fluentbit.inputTail.Mem_Buf_Limit | toString }} + {{- end }} + {{- if .Values.fluentbit.inputTail.Multiline_Flush }} + Multiline_Flush: {{ .Values.fluentbit.inputTail.Multiline_Flush | toString | quote }} + {{- end }} + {{- if .Values.fluentbit.inputTail.Skip_Long_Lines }} + Skip_Long_Lines: {{ .Values.fluentbit.inputTail.Skip_Long_Lines | toString | quote }} + {{- end }} + {{- end }} + {{- with (concat (.Values.tolerations) (.Values.fluentbit.tolerations)) }} + tolerations: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.fluentbit.resources }} + resources: {{- toYaml . | nindent 6 }} + {{- end }} +{{- end -}} + +{{- define "logging-operator.util.merge.fluentbitagent" -}} +{{/* Top context to expose fields like `.Release` and `.Values` */}} +{{- $top := first . -}} + +{{/* tpl is the template specific to the fluentbit implementation */}} +{{- $tpl := fromYaml (include (index . 1) $top) | default (dict ) -}} + +{{/* Generic is the shared rancher fluentbit setttings from `_generic_fluentbitagent.yaml` */}} +{{- $generic := fromYaml (include (index . 2) $top) | default (dict ) -}} + +{{/* values are from the values.yaml */}} +{{- $values := $top.Values.fluentbitAgentOverlay | default (dict ) -}} + +####### {{$generic}} + +{{/* the sources are merge right to left meaning tpl is the highest prcedence and values is the lowest */}} +{{- toYaml (merge $tpl $values $generic) -}} +{{- end -}} + +{{- define "logging-operator.fluentbitagent" -}} +{{- include "logging-operator.util.merge.fluentbitagent" (append . "logging-operator.fluentbitagent.tpl") -}} +{{- end -}} \ No newline at end of file diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/_generic_logging.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/_generic_logging.yaml new file mode 100644 index 0000000000..a143cdd9b8 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/_generic_logging.yaml @@ -0,0 +1,72 @@ +{{- define "logging-operator.logging.tpl" -}} +apiVersion: logging.banzaicloud.io/v1beta1 +kind: Logging +metadata: + namespace: {{ .Release.Namespace }} + labels: +{{ include "logging-operator.labels" . | indent 4 }} +spec: + controlNamespace: {{ .Release.Namespace }} + fluentd: + {{- with .Values.fluentd.logLevel }} + logLevel: {{ . }} + {{- end }} + image: + repository: {{ template "system_default_registry" . }}{{ .Values.images.fluentd.repository }} + tag: {{ .Values.images.fluentd.tag }} + configReloaderImage: + repository: {{ template "system_default_registry" . }}{{ .Values.images.config_reloader.repository }} + tag: {{ .Values.images.config_reloader.tag }} + {{- with .Values.fluentd.bufferStorageVolume }} + bufferStorageVolume: {{- toYaml . | nindent 6 }} + {{- end }} + disablePvc: {{ .Values.disablePvc }} + {{- if .Values.fluentd.replicas }} + scaling: + replicas: {{ .Values.fluentd.replicas }} + {{- end }} + security: + podSecurityContext: + {{- if .Values.global.cattle.psp.enabled }} + podSecurityPolicyCreate: true + roleBasedAccessControlCreate: true + {{- end }} + {{- with .Values.fluentd.env }} + envVars: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with (default .Values.tolerations .Values.fluentd.tolerations) }} + tolerations: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with (default .Values.nodeSelector .Values.fluentd.nodeSelector) }} + nodeSelector: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.fluentd.resources }} + resources: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.fluentd.livenessProbe }} + livenessProbe: {{- toYaml . | nindent 6 }} + {{- end }} +{{- end -}} + +{{- define "logging-operator.util.merge.logging" -}} +{{/* Top context to expose fields like `.Release` and `.Values` */}} +{{- $top := first . -}} + +{{/* tpl is the template specific to the logging implementation */}} +{{- $tpl := fromYaml (include (index . 1) $top) | default (dict ) -}} + +{{/* Generic is the shared rancher logging setttings from `_generic_logging.yaml` */}} +{{- $generic := fromYaml (include (index . 2) $top) | default (dict ) -}} + +{{/* values are from the values.yaml */}} +{{- $values := $top.Values.loggingOverlay | default (dict ) -}} + +####### {{$generic}} + +{{/* the sources are merge right to left meaning tpl is the highest prcedence and values is the lowest */}} +{{- toYaml (merge $tpl $values $generic) -}} +{{- end -}} + +{{- define "logging-operator.logging" -}} +{{- include "logging-operator.util.merge.logging" (append . "logging-operator.logging.tpl") -}} +{{- end -}} \ No newline at end of file diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/_helpers.tpl b/charts/rancher-logging/104.1.1+up4.8.0/templates/_helpers.tpl new file mode 100644 index 0000000000..43b6a5413f --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/_helpers.tpl @@ -0,0 +1,197 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "logging-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "logging-operator.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Expand the name of the release. +*/}} +{{- define "logging-operator.releasename" -}} +{{- default .Release.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Provides the namespace the chart will be installed in using the builtin .Release.Namespace, +or, if provided, a manually overwritten namespace value. +*/}} +{{- define "logging-operator.namespace" -}} +{{- if .Values.namespaceOverride -}} +{{ .Values.namespaceOverride -}} +{{- else -}} +{{ .Release.Namespace }} +{{- end -}} +{{- end -}} + + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "logging-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "logging-operator.labels" -}} +app.kubernetes.io/name: {{ include "logging-operator.name" . }} +helm.sh/chart: {{ include "logging-operator.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- else -}} +{{- "" -}} +{{- end -}} +{{- end -}} + +{{- define "windowsEnabled" }} +{{- if not (kindIs "invalid" .Values.global.cattle.windows) }} +{{- if not (kindIs "invalid" .Values.global.cattle.windows.enabled) }} +{{- if .Values.global.cattle.windows.enabled }} +true +{{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "windowsPathPrefix" -}} +{{- trimSuffix "/" (default "c:\\" .Values.global.cattle.rkeWindowsPathPrefix | replace "\\" "/" | replace "//" "/" | replace "c:" "C:") -}} +{{- end -}} + +{{- define "windowsKubernetesFilter" -}} +{{- printf "kubernetes.%s" ((include "windowsPathPrefix" .) | replace ":" "" | replace "/" ".") -}} +{{- end -}} + +{{- define "windowsInputTailMount" -}} +{{- (include "windowsPathPrefix" .) | replace "C:" "" -}} +{{- end -}} + +{{/* +Set the controlplane selector based on kubernetes distribution +*/}} +{{- define "controlplaneSelector" -}} +{{- $master := or .Values.additionalLoggingSources.rke2.enabled .Values.additionalLoggingSources.k3s.enabled -}} +{{- $defaultSelector := $master | ternary (dict "node-role.kubernetes.io/master" "true") (dict "node-role.kubernetes.io/controlplane" "true") -}} +{{ default $defaultSelector .Values.additionalLoggingSources.kubeAudit.nodeSelector | toYaml }} +{{- end -}} + +{{/* +Set kube-audit file path prefix based on distribution +*/}} +{{- define "kubeAuditPathPrefix" -}} +{{- if .Values.additionalLoggingSources.rke.enabled -}} +{{ default "/var/log/kube-audit" .Values.additionalLoggingSources.kubeAudit.pathPrefix }} +{{- else if .Values.additionalLoggingSources.rke2.enabled -}} +{{ default "/var/lib/rancher/rke2/server/logs" .Values.additionalLoggingSources.kubeAudit.pathPrefix }} +{{- else -}} +{{ required "Directory PathPrefix of the kube-audit location is required" .Values.additionalLoggingSources.kubeAudit.pathPrefix }} +{{- end -}} +{{- end -}} + +{{/* +Set kube-audit file name based on distribution +*/}} +{{- define "kubeAuditFilename" -}} +{{- if .Values.additionalLoggingSources.rke.enabled -}} +{{ default "audit-log.json" .Values.additionalLoggingSources.kubeAudit.auditFilename }} +{{- else if .Values.additionalLoggingSources.rke2.enabled -}} +{{ default "audit.log" .Values.additionalLoggingSources.kubeAudit.auditFilename }} +{{- else -}} +{{ required "Filename of the kube-audit log is required" .Values.additionalLoggingSources.kubeAudit.auditFilename }} +{{- end -}} +{{- end -}} + +{{/* +A shared list of custom parsers for the vairous fluentbit pods rancher creates +*/}} +{{- define "logging-operator.parsers" -}} +[PARSER] + Name klog + Format regex + Regex ^(?[IWEF])(?\d{4} \d{2}:\d{2}:\d{2}).\d{6} +?(?\d+) (?.+):(?\d+)] (?.+) + Time_Key timestamp + Time_Format %m%d %T + +[PARSER] + Name rancher + Format regex + Regex ^time="(?.+)" level=(?.+) msg="(?.+)"$ + Time_Key timestamp + Time_Format %FT%H:%M:%S +[PARSER] + Name etcd + Format json + Time_Key timestamp + Time_Format %FT%H:%M:%S.%L +{{- end -}} + +{{/* +Set kubernetes log options if they are configured +*/}} +{{- define "requireFilterKubernetes" -}} +{{- if or .Values.fluentbit.filterKubernetes.Merge_Log .Values.fluentbit.filterKubernetes.Merge_Log_Key .Values.fluentbit.filterKubernetes.Merge_Trim .Values.fluentbit.filterKubernetes.Merge_Parser -}} +true +{{- end -}} +{{- end -}} + +{{/*Fluent Bit Image Repository */}} +{{- define "logging-operator.fluentbitImageRepository" -}} +{{- if .Values.debug -}} +{{ template "system_default_registry" . }}{{ .Values.images.fluentbit_debug.repository }} +{{- else -}} +{{ template "system_default_registry" . }}{{ .Values.images.fluentbit.repository }} +{{- end -}} +{{- end -}} + +{{/*Fluent Bit Image Tag */}} +{{- define "logging-operator.fluentbitImageTag" -}} +{{- if .Values.debug -}} +{{ .Values.images.fluentbit_debug.tag }} +{{- else -}} +{{ .Values.images.fluentbit.tag }} +{{- end -}} +{{- end -}} + +{{/*Fluent Bit Image */}} +{{- define "logging-operator.fluentbitImage" -}} +{{ template "logging-operator.fluentbitImageRepository" . }}:{{ template "logging-operator.fluentbitImageTag" . }} +{{- end -}} + +{{/* +Formats the cluster domain as a suffix, e.g.: +.Values.clusterDomain == "", returns "" +.Values.clusterDomain == "cluster.local.", returns ".cluster.local." +*/}} +{{- define "logging-operator.clusterDomainAsSuffix" -}} +{{- if .Values.clusterDomain -}} +{{- printf ".%s" .Values.clusterDomain -}} +{{- end -}} +{{- end -}} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/clusterrole.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/clusterrole.yaml new file mode 100644 index 0000000000..1e2652a7ec --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/clusterrole.yaml @@ -0,0 +1,388 @@ +{{- if .Values.rbac.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "logging-operator.fullname" . }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - endpoints + - namespaces + - nodes + - nodes/proxy + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - watch +- apiGroups: + - "" + resources: + - persistentvolumeclaims + - pods + - serviceaccounts + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + - events.k8s.io + resources: + - events + verbs: + - create + - get + - list + - watch +- apiGroups: + - apps + resources: + - daemonsets + - replicasets + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + - extensions + resources: + - daemonsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + - extensions + resources: + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - '*' +- apiGroups: + - events.k8s.io + resources: + - events + verbs: + - get + - list + - watch +- apiGroups: + - extensions + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - extensions + - policy + resources: + - podsecuritypolicies + verbs: + - create + - delete + - get + - list + - patch + - update + - use + - watch +- apiGroups: + - logging-extensions.banzaicloud.io + resources: + - eventtailers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - logging-extensions.banzaicloud.io + resources: + - eventtailers/status + verbs: + - get + - patch + - update +- apiGroups: + - logging-extensions.banzaicloud.io + resources: + - hosttailers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - logging-extensions.banzaicloud.io + resources: + - hosttailers/status + verbs: + - get + - patch + - update +- apiGroups: + - logging.banzaicloud.io + resources: + - clusterflows + - clusteroutputs + - flows + - fluentbitagents + - fluentdconfigs + - loggings + - nodeagents + - outputs + - syslogngconfigs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - logging.banzaicloud.io + resources: + - clusterflows/status + - clusteroutputs/status + - flows/status + - fluentbitagents/status + - fluentdconfigs/status + - loggings/status + - nodeagents/status + - outputs/status + - syslogngconfigs/status + verbs: + - get + - patch + - update +- apiGroups: + - logging.banzaicloud.io + resources: + - loggingroutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - logging.banzaicloud.io + resources: + - loggingroutes/status + verbs: + - get + - patch + - update +- apiGroups: + - logging.banzaicloud.io + resources: + - loggings/finalizers + verbs: + - update +- apiGroups: + - logging.banzaicloud.io + resources: + - syslogngclusterflows + - syslogngclusteroutputs + - syslogngflows + - syslogngoutputs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - logging.banzaicloud.io + resources: + - syslogngclusterflows/status + - syslogngclusteroutputs/status + - syslogngflows/status + - syslogngoutputs/status + verbs: + - get + - patch + - update +- apiGroups: + - monitoring.coreos.com + resources: + - prometheusrules + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/clusterrolebinding.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..89d17d094f --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/clusterrolebinding.yaml @@ -0,0 +1,18 @@ +{{- if .Values.rbac.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "logging-operator.fullname" . }} + labels: +{{ include "logging-operator.labels" . | indent 4 }} +subjects: + - kind: ServiceAccount + name: {{ template "logging-operator.fullname" . }} + namespace: {{ include "logging-operator.namespace" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "logging-operator.fullname" . }} + + {{- end }} \ No newline at end of file diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/crds.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/crds.yaml new file mode 100644 index 0000000000..f573652d04 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/crds.yaml @@ -0,0 +1,6 @@ +{{- if .Values.createCustomResource -}} +{{- range $path, $bytes := .Files.Glob "crds/*.yaml" }} +{{ $.Files.Get $path }} +--- +{{- end }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/deployment.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/deployment.yaml new file mode 100644 index 0000000000..0cdf494e97 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "logging-operator.fullname" . }} + namespace: {{ include "logging-operator.namespace" . }} + labels: +{{ include "logging-operator.labels" . | indent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "logging-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "logging-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- with .Values.podLabels }} + {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + args: + {{- range .Values.extraArgs }} + - {{ . }} + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + ports: + - name: http + containerPort: {{ .Values.http.port }} + {{- with .Values.env }} + env: {{ toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.securityContext }} + securityContext: {{ toYaml .Values.securityContext | nindent 12 }} + {{- end }} + {{- with .Values.volumeMounts }} + volumeMounts: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumes }} + volumes: {{ toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.podSecurityContext }} + securityContext: {{ toYaml .Values.podSecurityContext | nindent 8 }} + {{- end }} + + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.rbac.serviceAccountName }} + serviceAccountName: {{ .Values.rbac.serviceAccountName }} + {{- else if .Values.rbac.enabled }} + serviceAccountName: {{ include "logging-operator.fullname" . }} + {{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/extra-manifests.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/extra-manifests.yaml new file mode 100644 index 0000000000..567f7bf329 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/clusterflows.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/clusterflows.yaml new file mode 100644 index 0000000000..3a1a46bee5 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/clusterflows.yaml @@ -0,0 +1,14 @@ +{{ if .Values.logging.enabled -}} +{{- range $clusterflow := .Values.logging.clusterFlows }} +--- +apiVersion: logging.banzaicloud.io/v1beta1 +kind: ClusterFlow +metadata: + name: {{ $clusterflow.name }} + namespace: {{ $.Values.logging.controlNamespace | default $.Release.Namespace }} + labels: +{{ include "logging-operator.labels" $ | indent 4 }} +spec: +{{ toYaml $clusterflow.spec | indent 2 }} +{{- end -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/clusteroutputs.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/clusteroutputs.yaml new file mode 100644 index 0000000000..60d9f30ae7 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/clusteroutputs.yaml @@ -0,0 +1,14 @@ +{{ if .Values.logging.enabled -}} +{{- range $clusteroutput := .Values.logging.clusterOutputs }} +--- +apiVersion: logging.banzaicloud.io/v1beta1 +kind: ClusterOutput +metadata: + name: {{ $clusteroutput.name }} + namespace: {{ $.Values.logging.controlNamespace | default $.Release.Namespace }} + labels: +{{ include "logging-operator.labels" $ | indent 4 }} +spec: +{{ toYaml $clusteroutput.spec | indent 2 }} +{{- end -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/eventtailer.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/eventtailer.yaml new file mode 100644 index 0000000000..830cf9b15d --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/eventtailer.yaml @@ -0,0 +1,41 @@ +{{- with $.Values.logging.eventTailer }} +{{- if and $.Values.logging.enabled .enabled }} +apiVersion: logging-extensions.banzaicloud.io/v1alpha1 +kind: EventTailer +metadata: + name: {{ .name }} +spec: + controlNamespace: {{ $.Values.logging.controlNamespace | default $.Release.Namespace }} + {{- with .image }} + image: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .pvc }} + {{- if .enabled }} + positionVolume: + pvc: + spec: + accessModes: {{ .accessModes }} + resources: + requests: + storage: {{ .storage }} + volumeMode: {{ .volumeMode }} + {{- with .storageClassName }} + storageClassName: {{ . }} + {{- end }} + {{- end }}{{/* end if enabled */}} + {{- end }}{{/* end with pvc */}} + {{- with .workloadMetaOverrides }} + workloadMetaOverrides: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .workloadOverrides }} + workloadOverrides: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .containerOverrides }} + containerOverrides: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }}{{/* end if enabled */}} +{{- end }}{{/* end with event-tailer */}} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/fluentbit.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/fluentbit.yaml new file mode 100644 index 0000000000..ad9bdcb319 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/fluentbit.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.logging.enabled (not .Values.logging.fluentbitDisabled) -}} +{{- $fluentbitSpec := .Values.logging.fluentbit }} +{{- if .Values.logging.loggingRef }} + {{- $fluentbitSpec := set .Values.logging.fluentbit "loggingRef" (default .Values.logging.loggingRef .Values.logging.fluentbit.loggingRef) -}} +{{- end }} + +apiVersion: logging.banzaicloud.io/v1beta1 +kind: FluentbitAgent +metadata: + name: {{ include "logging-operator.releasename" . }} + labels: {{ include "logging-operator.labels" . | nindent 4 }} +{{- if $fluentbitSpec }} +spec: {{- toYaml $fluentbitSpec | nindent 2 }} +{{- else }} +spec: {} +{{- end }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/hosttailer.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/hosttailer.yaml new file mode 100644 index 0000000000..a14d7c10b7 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/hosttailer.yaml @@ -0,0 +1,31 @@ +{{- with .Values.logging.hostTailer }} +{{- if and $.Values.logging.enabled .enabled }} +--- +apiVersion: logging-extensions.banzaicloud.io/v1alpha1 +kind: HostTailer +metadata: + name: {{ .name }} +spec: + {{- with .fileTailers }} + fileTailers: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .systemdTailers }} + systemdTailers: + {{- toYaml . | nindent 4 }} + {{- end }} + enableRecreateWorkloadOnImmutableFieldChange: {{ $.Values.logging.enableRecreateWorkloadOnImmutableFieldChange }} + {{- with .workloadMetaOverrides }} + workloadMetaOverrides: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .workloadOverrides }} + workloadOverrides: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .image }} + image: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/logging.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/logging.yaml new file mode 100644 index 0000000000..0adf992bfc --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/logging/logging.yaml @@ -0,0 +1,60 @@ +{{ if .Values.logging.enabled -}} +apiVersion: logging.banzaicloud.io/v1beta1 +kind: Logging +metadata: + name: {{ include "logging-operator.releasename" . }} + labels: +{{ include "logging-operator.labels" . | indent 4 }} +spec: + {{- with .Values.logging.loggingRef }} + loggingRef: {{ . }} + {{- end }} + {{- with .Values.logging.flowConfigCheckDisabled }} + flowConfigCheckDisabled: {{ . }} + {{- end }} + {{- with .Values.logging.skipInvalidResources }} + skipInvalidResources: {{ . }} + {{- end }} + {{- with .Values.logging.flowConfigOverride }} + flowConfigOverride: {{ . }} + {{- end }} + {{- if (not .Values.logging.fluentdDisabled) }} + {{- if .Values.logging.fluentd }} + fluentd: {{- toYaml .Values.logging.fluentd | nindent 4 }} + {{- else }} + fluentd: {} + {{- end }} + {{- end }} + {{- with .Values.logging.syslogNG }} + syslogNG: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.logging.defaultFlow }} + defaultFlow: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.logging.errorOutputRef }} + errorOutputRef: {{ . }} + {{- end }} + {{- with .Values.logging.globalFilters }} + globalFilters: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.logging.watchNamespaces }} + watchNamespaces: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.logging.watchNamespaceSelector }} + watchNamespaceSelector: {{- toYaml . | nindent 4 }} + {{- end }} + clusterDomain: {{ .Values.logging.clusterDomain }} + controlNamespace: {{ .Values.logging.controlNamespace | default .Release.Namespace }} + {{- with .Values.logging.allowClusterResourcesFromAllNamespaces }} + allowClusterResourcesFromAllNamespaces: {{ . }} + {{- end }} + {{- with .Values.logging.nodeAgents }} + nodeAgents: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.logging.enableRecreateWorkloadOnImmutableFieldChange }} + enableRecreateWorkloadOnImmutableFieldChange: {{ . }} + {{- end }} + {{- with .Values.logging.configCheck }} + configCheck: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/aks/fluentbitagent.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/aks/fluentbitagent.yaml new file mode 100644 index 0000000000..1663bc0f4b --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/aks/fluentbitagent.yaml @@ -0,0 +1,17 @@ +{{- define "logging-operator.fluentbitagent.aks" -}} +{{- $logPath := "/var/log/azure/kubelet-status.log" -}} +metadata: + name: {{ .Release.Name }}-aks +spec: + disableKubernetesFilter: true + extraVolumeMounts: + - source: {{ $logPath }} + destination: {{ $logPath }} + readOnly: true + inputTail: + Tag: "aks" + Path: {{ $logPath }} +{{- end -}} +{{- if .Values.additionalLoggingSources.aks.enabled }} +{{- include "logging-operator.fluentbitagent" (list . "logging-operator.fluentbitagent.aks") -}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/aks/logging.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/aks/logging.yaml new file mode 100644 index 0000000000..6341387a68 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/aks/logging.yaml @@ -0,0 +1,7 @@ +{{- define "logging-operator.logging.aks" -}} +metadata: + name: {{ .Release.Name }}-aks +{{- end -}} +{{- if .Values.additionalLoggingSources.aks.enabled }} +{{- include "logging-operator.logging" (list . "logging-operator.logging.aks") -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/eks/fluentbitagent.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/eks/fluentbitagent.yaml new file mode 100644 index 0000000000..10d49bb582 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/eks/fluentbitagent.yaml @@ -0,0 +1,18 @@ +{{- define "logging-operator.fluentbitagent.eks" -}} +{{- $logPath := "/var/log/messages" -}} +metadata: + name: {{ .Release.Name }}-eks +spec: + disableKubernetesFilter: true + extraVolumeMounts: + - source: {{ $logPath }} + destination: {{ $logPath }} + readOnly: true + inputTail: + Tag: "eks" + Path: {{ $logPath }} + Parser: "syslog" +{{- end -}} +{{- if .Values.additionalLoggingSources.eks.enabled }} +{{- include "logging-operator.fluentbitagent" (list . "logging-operator.fluentbitagent.eks") -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/eks/logging.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/eks/logging.yaml new file mode 100644 index 0000000000..5d396bd696 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/eks/logging.yaml @@ -0,0 +1,17 @@ +{{- define "logging-operator.logging.eks" -}} +metadata: + name: {{ .Release.Name }}-eks +spec: + fluentd: + {{- if .Values.loggingServiceAccountAnnotations.eks -}} + serviceAccount: + metadata: + annotations: + {{- with .Values.loggingServiceAccountAnnotations.eks }} + {{ toYaml . | indent 8 }} + {{- end }} + {{- end }} +{{- end -}} +{{- if .Values.additionalLoggingSources.eks.enabled }} +{{- include "logging-operator.logging" (list . "logging-operator.logging.eks") -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/gke/fluentbitagent.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/gke/fluentbitagent.yaml new file mode 100644 index 0000000000..c54d50c703 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/gke/fluentbitagent.yaml @@ -0,0 +1,17 @@ +{{- define "logging-operator.fluentbitagent.gke" -}} +{{- $logPath := "/var/log/kube-proxy.log" -}} +metadata: + name: {{ .Release.Name }}-gke +spec: + disableKubernetesFilter: true + extraVolumeMounts: + - source: {{ $logPath }} + destination: {{ $logPath }} + readOnly: true + inputTail: + Tag: "gke" + Path: {{ $logPath }} +{{- end -}} +{{- if .Values.additionalLoggingSources.gke.enabled }} +{{- include "logging-operator.fluentbitagent" (list . "logging-operator.fluentbitagent.gke") -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/gke/logging.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/gke/logging.yaml new file mode 100644 index 0000000000..3271599b95 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/gke/logging.yaml @@ -0,0 +1,7 @@ +{{- define "logging-operator.logging.gke" -}} +metadata: + name: {{ .Release.Name }}-gke +{{- end -}} +{{- if .Values.additionalLoggingSources.gke.enabled }} +{{- include "logging-operator.logging" (list . "logging-operator.logging.gke") -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/configmap.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/configmap.yaml new file mode 100644 index 0000000000..aa454c8adf --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/configmap.yaml @@ -0,0 +1,57 @@ +{{- if and .Values.additionalLoggingSources.k3s.enabled (eq .Values.additionalLoggingSources.k3s.container_engine "systemd") }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-k3s + labels: +{{ include "logging-operator.labels" . | indent 4 }} +data: + fluent-bit.conf: | + [SERVICE] + Flush 1 + Grace 5 + Daemon Off + Log_Level info + Coro_Stack_Size 24576 + Parsers_File parsers.conf + + [INPUT] + Name systemd + Tag k3s + Path {{ .Values.systemdLogPath }} + Systemd_Filter _SYSTEMD_UNIT=k3s.service + {{- if .Values.additionalLoggingSources.k3s.stripUnderscores }} + Strip_Underscores On + {{- end }} + Systemd_Filter _SYSTEMD_UNIT=k3s-agent.service + + [FILTER] + Name parser + Match * + Key_Name MESSAGE + Parser klog + Reserve_Data On + + [FILTER] + Name parser + Match * + Key_Name MESSAGE + Parser rancher + Reserve_Data On + + [FILTER] + Name parser + Match * + Key_Name MESSAGE + Parser etcd + Reserve_Data On + + [OUTPUT] + Name forward + Match * + Host {{ .Release.Name }}-root-fluentd.{{ .Release.Namespace }}.svc + Port 24240 + Retry_Limit False + parsers.conf: | +{{ include "logging-operator.parsers" . | indent 4 }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/daemonset.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/daemonset.yaml new file mode 100644 index 0000000000..e80c2b1c8b --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/daemonset.yaml @@ -0,0 +1,110 @@ +{{- if and .Values.additionalLoggingSources.k3s.enabled (eq .Values.additionalLoggingSources.k3s.container_engine "systemd") }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: "{{ .Release.Name }}-k3s-journald-aggregator" + namespace: "{{ .Release.Namespace }}" +spec: + selector: + matchLabels: + name: {{ .Release.Name }}-k3s-journald-aggregator + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/loggings/k3s/configmap.yaml") . | sha256sum }} + name: "{{ .Release.Name }}-k3s-journald-aggregator" + namespace: "{{ .Release.Namespace }}" + labels: + name: {{ .Release.Name }}-k3s-journald-aggregator + spec: + containers: + - name: fluentbit + image: "{{ template "logging-operator.fluentbitImage" . }}" + {{- if .Values.global.seLinux.enabled }} + securityContext: + seLinuxOptions: + type: rke_logreader_t + {{- end }} + volumeMounts: + - mountPath: /fluent-bit/etc/ + name: config + - mountPath: {{ .Values.systemdLogPath | default "/var/log/journal" }} + name: journal + readOnly: true + - mountPath: /etc/machine-id + name: machine-id + readOnly: true + {{- with .Values.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: "{{ .Release.Name }}-k3s-journald-aggregator" + volumes: + - name: config + configMap: + name: "{{ .Release.Name }}-k3s" + - name: journal + hostPath: + path: {{ .Values.systemdLogPath | default "/var/log/journal" }} + - name: machine-id + hostPath: + path: /etc/machine-id +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ .Release.Name }}-k3s-journald-aggregator" + namespace: "{{ .Release.Namespace }}" +{{- if .Values.global.cattle.psp.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ .Release.Name }}-k3s-journald-aggregator" +rules: + - apiGroups: + - policy + resourceNames: + - "{{ .Release.Name }}-k3s-journald-aggregator" + resources: + - podsecuritypolicies + verbs: + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ .Release.Name }}-k3s-journald-aggregator" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ .Release.Name }}-k3s-journald-aggregator" +subjects: + - kind: ServiceAccount + name: "{{ .Release.Name }}-k3s-journald-aggregator" +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: "{{ .Release.Name }}-k3s-journald-aggregator" + namespace: "{{ .Release.Namespace }}" +spec: + allowPrivilegeEscalation: false + fsGroup: + rule: RunAsAny + readOnlyRootFilesystem: true + runAsUser: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - configMap + - emptyDir + - secret + - hostPath +{{- end }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/fluentbitagent.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/fluentbitagent.yaml new file mode 100644 index 0000000000..9b3c08a0f2 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/fluentbitagent.yaml @@ -0,0 +1,18 @@ +{{- define "logging-operator.fluentbitagent.k3s-openrc" -}} +{{- $logPath := "/var/log/k3s.log" -}} +metadata: + name: {{ .Release.Name }}-k3s +spec: + disableKubernetesFilter: true + extraVolumeMounts: + - source: {{ $logPath }} + destination: {{ $logPath }} + readOnly: true + inputTail: + Tag: "k3s" + Path: {{ $logPath }} + Path_Key: filename +{{- end -}} +{{- if and .Values.additionalLoggingSources.k3s.enabled (eq .Values.additionalLoggingSources.k3s.container_engine "openrc")}} +{{- include "logging-operator.fluentbitagent" (list . "logging-operator.fluentbitagent.k3s-openrc") -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/logging-k3s-openrc.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/logging-k3s-openrc.yaml new file mode 100644 index 0000000000..efbde42928 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/k3s/logging-k3s-openrc.yaml @@ -0,0 +1,7 @@ +{{- define "logging-operator.logging.k3s-openrc" -}} +metadata: + name: {{ .Release.Name }}-k3s +{{- end -}} +{{- if and .Values.additionalLoggingSources.k3s.enabled (eq .Values.additionalLoggingSources.k3s.container_engine "openrc")}} +{{- include "logging-operator.logging" (list . "logging-operator.logging.k3s-openrc") -}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/kube-audit/fluentbitagent.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/kube-audit/fluentbitagent.yaml new file mode 100644 index 0000000000..92f006b98d --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/kube-audit/fluentbitagent.yaml @@ -0,0 +1,21 @@ +{{- define "logging-operator.fluentbitagent.kube-audit" -}} +metadata: + name: {{ .Release.Name }}-kube-audit +spec: + disableKubernetesFilter: true + extraVolumeMounts: + - source: {{ template "kubeAuditPathPrefix" . }} + destination: "/kube-audit-logs" + readOnly: true + inputTail: + Tag: {{ .Values.additionalLoggingSources.kubeAudit.fluentbit.logTag }} + Path: /kube-audit-logs/{{ template "kubeAuditFilename" . }} + Parser: json + {{- with (concat (.Values.tolerations) (.Values.fluentbit.tolerations) (.Values.additionalLoggingSources.kubeAudit.fluentbit.tolerations)) }} + tolerations: {{- toYaml . | nindent 6 }} + {{- end }} + nodeSelector: {{ include "controlplaneSelector" . | nindent 6 }} +{{- end -}} +{{- if .Values.additionalLoggingSources.kubeAudit.enabled }} +{{- include "logging-operator.fluentbitagent" (list . "logging-operator.fluentbitagent.kube-audit") -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/kube-audit/logging.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/kube-audit/logging.yaml new file mode 100644 index 0000000000..1e063b9e6e --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/kube-audit/logging.yaml @@ -0,0 +1,11 @@ +{{- define "logging-operator.logging.kube-audit" -}} +metadata: + name: {{ .Release.Name }}-kube-audit +spec: + {{- if .Values.additionalLoggingSources.kubeAudit.loggingRef }} + loggingRef: {{ .Values.additionalLoggingSources.kubeAudit.loggingRef }} + {{- end }} +{{- end -}} +{{- if .Values.additionalLoggingSources.kubeAudit.enabled }} +{{- include "logging-operator.logging" (list . "logging-operator.logging.kube-audit") -}} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke/configmap.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke/configmap.yaml new file mode 100644 index 0000000000..252572a4ef --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke/configmap.yaml @@ -0,0 +1,29 @@ +{{- if .Values.additionalLoggingSources.rke.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-rke + labels: +{{ include "logging-operator.labels" . | indent 4 }} +data: + fluent-bit.conf: | + [SERVICE] + Log_Level {{ .Values.additionalLoggingSources.rke.fluentbit.log_level }} + Parsers_File parsers.conf + + [INPUT] + Tag rke + Name tail + Path_Key filename + Parser docker + DB /tail-db/tail-containers-state.db + Mem_Buf_Limit {{ .Values.additionalLoggingSources.rke.fluentbit.mem_buffer_limit }} + Path /var/lib/rancher/rke/log/*.log + + [OUTPUT] + Name forward + Match * + Host {{ .Release.Name }}-root-fluentd.{{ .Release.Namespace }}.svc + Port 24240 + Retry_Limit False +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke/daemonset.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke/daemonset.yaml new file mode 100644 index 0000000000..cc39a5cc49 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke/daemonset.yaml @@ -0,0 +1,122 @@ +{{- if .Values.additionalLoggingSources.rke.enabled }} +{{- $containers := printf "%s/containers/" (default "/var/lib/docker" .Values.global.dockerRootDirectory) }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: "{{ .Release.Name }}-rke-aggregator" + namespace: "{{ .Release.Namespace }}" +spec: + selector: + matchLabels: + name: {{ .Release.Name }}-rke-aggregator + template: + metadata: + name: "{{ .Release.Name }}-rke-aggregator" + namespace: "{{ .Release.Namespace }}" + labels: + name: {{ .Release.Name }}-rke-aggregator + spec: + containers: + - name: fluentbit + image: "{{ template "logging-operator.fluentbitImage" . }}" + volumeMounts: + - mountPath: /var/lib/rancher/rke/log/ + name: indir + - mountPath: {{ $containers }} + name: containers + - mountPath: /tail-db + name: positiondb + - mountPath: /fluent-bit/etc/fluent-bit.conf + name: config + subPath: fluent-bit.conf + {{- if .Values.global.seLinux.enabled }} + securityContext: + seLinuxOptions: + type: rke_logreader_t + {{- end }} + volumes: + - name: indir + hostPath: + path: /var/lib/rancher/rke/log/ + type: DirectoryOrCreate + - name: containers + hostPath: + path: {{ $containers }} + type: DirectoryOrCreate + - name: positiondb + emptyDir: {} + - name: config + configMap: + name: "{{ .Release.Name }}-rke" + serviceAccountName: "{{ .Release.Name }}-rke-aggregator" + {{- $total_tolerations := concat (.Values.tolerations) (.Values.fluentbit.tolerations) }} + {{- with $total_tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ .Release.Name }}-rke-aggregator" + namespace: "{{ .Release.Namespace }}" +{{- if .Values.global.cattle.psp.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ .Release.Name }}-rke-aggregator" +rules: + - apiGroups: + - policy + resourceNames: + - "{{ .Release.Name }}-rke-aggregator" + resources: + - podsecuritypolicies + verbs: + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ .Release.Name }}-rke-aggregator" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ .Release.Name }}-rke-aggregator" +subjects: + - kind: ServiceAccount + name: "{{ .Release.Name }}-rke-aggregator" +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: "{{ .Release.Name }}-rke-aggregator" + namespace: "{{ .Release.Namespace }}" +spec: + allowPrivilegeEscalation: false + allowedHostPaths: + - pathPrefix: {{ $containers }} + readOnly: false + - pathPrefix: /var/lib/rancher/rke/log/ + readOnly: false + - pathPrefix: /var/lib/rancher/logging/ + readOnly: false + fsGroup: + rule: RunAsAny + readOnlyRootFilesystem: true + runAsUser: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - configMap + - emptyDir + - secret + - hostPath +{{- end }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke2/configmap.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke2/configmap.yaml new file mode 100644 index 0000000000..3ca20be226 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke2/configmap.yaml @@ -0,0 +1,69 @@ +{{- if .Values.additionalLoggingSources.rke2.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-rke2 + labels: +{{ include "logging-operator.labels" . | indent 4 }} +data: + fluent-bit.conf: | + [SERVICE] + Flush 1 + Grace 5 + Daemon Off + Log_Level info + Coro_Stack_Size 24576 + Parsers_File parsers.conf + + [INPUT] + Name systemd + Tag rke2 + Path {{ .Values.systemdLogPath }} + Systemd_Filter _SYSTEMD_UNIT=rke2-server.service + Systemd_Filter _SYSTEMD_UNIT=rke2-agent.service + {{- if .Values.additionalLoggingSources.rke2.stripUnderscores }} + Strip_Underscores On + {{- end }} + + [INPUT] + Name tail + Tag rke2 + Path /var/lib/rancher/rke2/agent/logs/kubelet.log + + [FILTER] + Name parser + Match * + Key_Name log + Parser klog + Reserve_Data On + + [FILTER] + Name parser + Match * + Key_Name MESSAGE + Parser klog + Reserve_Data On + + [FILTER] + Name parser + Match * + Key_Name MESSAGE + Parser rancher + Reserve_Data On + + [FILTER] + Name parser + Match * + Key_Name MESSAGE + Parser etcd + Reserve_Data On + + [OUTPUT] + Name forward + Match * + Host {{ .Release.Name }}-root-fluentd.{{ .Release.Namespace }}.svc + Port 24240 + Retry_Limit False + parsers.conf: | +{{ include "logging-operator.parsers" . | indent 4 }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke2/daemonset.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke2/daemonset.yaml new file mode 100644 index 0000000000..8f54b718ee --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/rke2/daemonset.yaml @@ -0,0 +1,116 @@ +{{- if .Values.additionalLoggingSources.rke2.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: "{{ .Release.Name }}-rke2-journald-aggregator" + namespace: "{{ .Release.Namespace }}" +spec: + selector: + matchLabels: + name: {{ .Release.Name }}-rke2-journald-aggregator + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/loggings/rke2/configmap.yaml") . | sha256sum }} + name: "{{ .Release.Name }}-rke2-journald-aggregator" + namespace: "{{ .Release.Namespace }}" + labels: + name: {{ .Release.Name }}-rke2-journald-aggregator + spec: + containers: + - name: fluentbit + image: "{{ template "logging-operator.fluentbitImage" . }}" + {{- if .Values.global.seLinux.enabled }} + securityContext: + seLinuxOptions: + type: rke_logreader_t + {{- end }} + volumeMounts: + - mountPath: /fluent-bit/etc/ + name: config + - mountPath: {{ .Values.systemdLogPath | default "/var/log/journal" }} + name: journal + readOnly: true + - mountPath: "/var/lib/rancher/rke2/agent/logs" + name: kubelet + readOnly: true + - mountPath: /etc/machine-id + name: machine-id + readOnly: true + {{- with .Values.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: "{{ .Release.Name }}-rke2-journald-aggregator" + volumes: + - name: config + configMap: + name: "{{ .Release.Name }}-rke2" + - name: journal + hostPath: + path: {{ .Values.systemdLogPath | default "/var/log/journal" }} + - name: kubelet + hostPath: + path: "/var/lib/rancher/rke2/agent/logs" + - name: machine-id + hostPath: + path: /etc/machine-id +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ .Release.Name }}-rke2-journald-aggregator" + namespace: "{{ .Release.Namespace }}" +{{- if .Values.global.cattle.psp.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ .Release.Name }}-rke2-journald-aggregator" +rules: + - apiGroups: + - policy + resourceNames: + - "{{ .Release.Name }}-rke2-journald-aggregator" + resources: + - podsecuritypolicies + verbs: + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ .Release.Name }}-rke2-journald-aggregator" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ .Release.Name }}-rke2-journald-aggregator" +subjects: + - kind: ServiceAccount + name: "{{ .Release.Name }}-rke2-journald-aggregator" +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: "{{ .Release.Name }}-rke2-journald-aggregator" + namespace: "{{ .Release.Namespace }}" +spec: + allowPrivilegeEscalation: false + fsGroup: + rule: RunAsAny + readOnlyRootFilesystem: true + runAsUser: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - configMap + - emptyDir + - secret + - hostPath +{{- end }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/root/fluentbitagent.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/root/fluentbitagent.yaml new file mode 100644 index 0000000000..2816b7f911 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/root/fluentbitagent.yaml @@ -0,0 +1,29 @@ +{{- define "logging-operator.fluentbitagent.root" -}} +{{- $containerLogPath := printf "%s/containers/" (default "/var/lib/docker" .Values.global.dockerRootDirectory) }} +metadata: + name: "{{ .Release.Name }}-root" +spec: + {{- if .Values.global.dockerRootDirectory }} + mountPath: {{ $containerLogPath }} + extraVolumeMounts: + - source: {{ $containerLogPath }} + destination: {{ $containerLogPath }} + readOnly: true + {{- end }} + {{- if (include "requireFilterKubernetes" .) }} + filterKubernetes: + {{- if .Values.fluentbit.filterKubernetes.Merge_Log }} + Merge_Log: "{{ .Values.fluentbit.filterKubernetes.Merge_Log }}" + {{- end }} + {{- if .Values.fluentbit.filterKubernetes.Merge_Log_Key }} + Merge_Log_Key: "{{ .Values.fluentbit.filterKubernetes.Merge_Log_Key }}" + {{- end }} + {{- if .Values.fluentbit.filterKubernetes.Merge_Log_Trim }} + Merge_Log_Trim: "{{ .Values.fluentbit.filterKubernetes.Merge_Log_Trim }}" + {{- end }} + {{- if .Values.fluentbit.filterKubernetes.Merge_Parser }} + Merge_Parser: "{{ .Values.fluentbit.filterKubernetes.Merge_Parser }}" + {{- end }} + {{- end }} +{{- end -}} +{{- include "logging-operator.fluentbitagent" (list . "logging-operator.fluentbitagent.root") -}} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/root/logging.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/root/logging.yaml new file mode 100644 index 0000000000..e225815e1c --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/loggings/root/logging.yaml @@ -0,0 +1,67 @@ +{{- define "logging-operator.logging.root" -}} +metadata: + name: "{{ .Release.Name }}-root" +spec: + {{- if (include "windowsEnabled" .) }} + nodeAgents: + - name: win-agent + profile: windows + nodeAgentFluentbit: + daemonSet: + spec: + template: + spec: + containers: + - image: {{ template "system_default_registry" . }}{{ .Values.images.nodeagent_fluentbit.repository }}:{{ .Values.images.nodeagent_fluentbit.tag }} + name: fluent-bit + tls: + enabled: {{ .Values.nodeAgents.tls.enabled | default false }} + {{- if .Values.additionalLoggingSources.rke.enabled }} + - name: win-agent-rke + profile: windows + nodeAgentFluentbit: + filterKubernetes: + Kube_Tag_Prefix: "{{ template "windowsKubernetesFilter" . }}.var.lib.rancher.rke.log." + inputTail: + Path: "{{ template "windowsPathPrefix" . }}/var/lib/rancher/rke/log" + {{- if .Values.fluentbit.inputTail.Buffer_Chunk_Size }} + Buffer_Chunk_Size: {{ .Values.fluentbit.inputTail.Buffer_Chunk_Size | toString }} + {{- end }} + {{- if .Values.fluentbit.inputTail.Buffer_Max_Size }} + Buffer_Max_Size: {{ .Values.fluentbit.inputTail.Buffer_Max_Size | toString }} + {{- end }} + {{- if .Values.fluentbit.inputTail.Mem_Buf_Limit }} + Mem_Buf_Limit: {{ .Values.fluentbit.inputTail.Mem_Buf_Limit | toString }} + {{- end }} + {{- if .Values.fluentbit.inputTail.Multiline_Flush }} + Multiline_Flush: {{ .Values.fluentbit.inputTail.Multiline_Flush | toString | quote }} + {{- end }} + {{- if .Values.fluentbit.inputTail.Skip_Long_Lines }} + Skip_Long_Lines: {{ .Values.fluentbit.inputTail.Skip_Long_Lines | toString | quote }} + {{- end }} + extraVolumeMounts: + - source: "{{ template "windowsInputTailMount" . }}/var/lib/rancher/rke/log" + destination: "{{ template "windowsInputTailMount" . }}/var/lib/rancher/rke/log" + readOnly: true + daemonSet: + spec: + template: + spec: + containers: + - image: "{{ template "system_default_registry" . }}{{ .Values.images.nodeagent_fluentbit.repository }}:{{ .Values.images.nodeagent_fluentbit.tag }}" + name: fluent-bit + tls: + enabled: {{ .Values.nodeAgents.tls.enabled | default false }} + {{- end }} + {{- end }} + fluentd: + {{- if .Values.loggingServiceAccountAnnotations.root }} + serviceAccount: + metadata: + annotations: + {{- with .Values.loggingServiceAccountAnnotations.root }} + {{ toYaml . | indent 8 }} + {{- end }} + {{- end -}} +{{- end -}} +{{- include "logging-operator.logging" (list . "logging-operator.logging.root") -}} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/service.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/service.yaml new file mode 100644 index 0000000000..f419ae2c48 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "logging-operator.fullname" . }} + namespace: {{ include "logging-operator.namespace" . }} + labels: +{{ include "logging-operator.labels" . | indent 4 }} +spec: + type: ClusterIP + {{- with .Values.http.service.clusterIP }} + clusterIP: {{ . }} + {{- end }} + ports: + - port: {{ .Values.http.port }} + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "logging-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/service_monitor.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/service_monitor.yaml new file mode 100644 index 0000000000..fcd86b07a9 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/service_monitor.yaml @@ -0,0 +1,30 @@ +{{ if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.monitoring.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "logging-operator.fullname" . }} + namespace: {{ include "logging-operator.namespace" . }} + labels: +{{ include "logging-operator.labels" . | indent 4 }} +{{- with .Values.monitoring.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + selector: + matchLabels: +{{ include "logging-operator.labels" . | indent 6 }} + endpoints: + - port: http + path: /metrics + {{- with .Values.monitoring.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.monitoring.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 4 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "logging-operator.namespace" . }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/serviceaccount.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/serviceaccount.yaml new file mode 100644 index 0000000000..bb97cf1084 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if .Values.rbac.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "logging-operator.fullname" . }} + namespace: {{ include "logging-operator.namespace" . }} + labels: +{{ include "logging-operator.labels" . | indent 4 }} +{{- with .Values.serviceAccount.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/test_receiver.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/test_receiver.yaml new file mode 100644 index 0000000000..af0b5f4dcc --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/test_receiver.yaml @@ -0,0 +1,53 @@ +{{ if .Values.testReceiver.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "logging-operator.releasename" . }}-test-receiver + namespace: {{ include "logging-operator.namespace" . }} +spec: + type: ClusterIP + ports: + - port: {{ .Values.testReceiver.port }} + targetPort: receiver + protocol: TCP + name: receiver + selector: + app.kubernetes.io/name: {{ include "logging-operator.releasename" . }}-test-receiver + app.kubernetes.io/instance: {{ .Release.Name }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "logging-operator.releasename" . }}-test-receiver + namespace: {{ include "logging-operator.namespace" . }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ include "logging-operator.releasename" . }}-test-receiver + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "logging-operator.releasename" . }}-test-receiver + app.kubernetes.io/instance: {{ .Release.Name }} + annotations: + fluentbit.io/exclude: "true" + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.testReceiver.image }}" + args: + {{- range .Values.testReceiver.args }} + - {{ . }} + {{- end }} + imagePullPolicy: {{ .Values.testReceiver.pullPolicy }} + resources: + {{- toYaml .Values.testReceiver.resources | nindent 12 }} + ports: + - name: receiver + containerPort: {{ .Values.testReceiver.port }} +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/userrole.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/userrole.yaml new file mode 100644 index 0000000000..82c3200b9c --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/userrole.yaml @@ -0,0 +1,39 @@ +{{- if .Values.rbac.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "logging-operator.fullname" . }}-edit + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" +rules: +- apiGroups: + - logging.banzaicloud.io + resources: + - flows + - outputs + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - logging.banzaicloud.io + resources: + - syslogngflows + - syslogngoutputs + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/userroles.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/userroles.yaml new file mode 100644 index 0000000000..f4136b09a4 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/userroles.yaml @@ -0,0 +1,35 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "logging-admin" + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" +rules: + - apiGroups: + - "logging.banzaicloud.io" + resources: + - flows + - outputs + verbs: + - "*" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "logging-view" + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-view: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" +rules: + - apiGroups: + - "logging.banzaicloud.io" + resources: + - flows + - outputs + - clusterflows + - clusteroutputs + verbs: + - get + - list + - watch diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/validate-install-crd.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..5184c85c47 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/validate-install-crd.yaml @@ -0,0 +1,29 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "logging-extensions.banzaicloud.io/v1alpha1/EventTailer" false -}} +# {{- set $found "logging-extensions.banzaicloud.io/v1alpha1/HostTailer" false -}} +# {{- set $found "logging.banzaicloud.io/v1alpha1/ClusterFlow" false -}} +# {{- set $found "logging.banzaicloud.io/v1alpha1/ClusterOutput" false -}} +# {{- set $found "logging.banzaicloud.io/v1alpha1/Flow" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/FluentbitAgent" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/FluentdConfig" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/LoggingRoute" false -}} +# {{- set $found "logging.banzaicloud.io/v1alpha1/Logging" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/NodeAgent" false -}} +# {{- set $found "logging.banzaicloud.io/v1alpha1/Output" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/SyslogNGClusterFlow" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/SyslogNGClusterOutput" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/SyslogNGConfig" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/SyslogNGFlow" false -}} +# {{- set $found "logging.banzaicloud.io/v1beta1/SyslogNGOutput" 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-logging/104.1.1+up4.8.0/templates/validate-install.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/validate-install.yaml new file mode 100644 index 0000000000..bd624cc4b4 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/templates/validate-install.yaml @@ -0,0 +1,5 @@ +#{{- if .Values.global.dockerRootDirectory }} +#{{- if or (hasSuffix "/containers" .Values.global.dockerRootDirectory) (hasSuffix "/" .Values.global.dockerRootDirectory) }} +#{{- required "global.dockerRootDirectory must not end with suffix: '/' or '/containers'" "" -}} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-logging/104.1.1+up4.8.0/templates/validate-psp-install.yaml b/charts/rancher-logging/104.1.1+up4.8.0/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/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-logging/104.1.1+up4.8.0/values-logging-example.yaml b/charts/rancher-logging/104.1.1+up4.8.0/values-logging-example.yaml new file mode 100644 index 0000000000..b7068af4a0 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/values-logging-example.yaml @@ -0,0 +1,24 @@ +nameOverride: example + +# given we use `nameOverride: example` if testReceiver is enabled we can send http metrics to http://example-test-receiver:8080 +testReceiver: + enabled: true + +logging: + enabled: true + clusterFlows: + - name: all + spec: + match: + - select: {} + globalOutputRefs: ["http"] + clusterOutputs: + - name: http + spec: + http: + endpoint: http://example-test-receiver:8080 + content_type: application/json + buffer: + type: memory + timekey: 1s + timekey_wait: 1s diff --git a/charts/rancher-logging/104.1.1+up4.8.0/values.yaml b/charts/rancher-logging/104.1.1+up4.8.0/values.yaml new file mode 100644 index 0000000000..b47f091587 --- /dev/null +++ b/charts/rancher-logging/104.1.1+up4.8.0/values.yaml @@ -0,0 +1,484 @@ +# Default values for logging-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: rancher/mirrored-kube-logging-logging-operator + tag: 4.8.0 + pullPolicy: IfNotPresent + +env: [] +volumes: [] +volumeMounts: [] + +extraArgs: + - -enable-leader-election=true +imagePullSecrets: [] + +# -- A name in place of the chart name for `app:` labels. +nameOverride: "" + +# -- A name to substitute for the full names of resources. +fullnameOverride: "" + +# -- A namespace override for the app. +namespaceOverride: "" + +# -- Define annotations for logging-operator pods. +annotations: {} + +# -- Deploy CRDs used by Logging Operator. +createCustomResource: false + +http: + # -- HTTP listen port number. + port: 8080 + + # -- Service definition for query http service. + service: + type: ClusterIP + clusterIP: None + # Annotations to query http service + annotations: {} + # Labels to query http service + labels: {} + +rbac: + # -- Create rbac service account and roles. + enabled: true + + # specify service account manually + # serviceAccountName: custom + +monitoring: + serviceMonitor: + # -- Create a Prometheus Operator ServiceMonitor object. + enabled: false + + additionalLabels: {} + metricRelabelings: [] + relabelings: [] + +# -- Pod SecurityContext for Logging operator. [More info](https://kubernetes.io/docs/concepts/policy/security-context/) +## 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/ +podSecurityContext: {} +# runAsNonRoot: true +# runAsUser: 1000 +# fsGroup: 2000 + +# -- Container SecurityContext for Logging operator. [More info](https://kubernetes.io/docs/concepts/policy/security-context/) +securityContext: {} +# allowPrivilegeEscalation: false +# readOnlyRootFilesystem: true + # capabilities: + # drop: ["ALL"] + +# -- Operator priorityClassName. +priorityClassName: {} + +serviceAccount: + # -- Define annotations for logging-operator ServiceAccount. + annotations: {} + +# -- CPU/Memory resource requests/limits +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +# -- Node Tolerations +tolerations: [] + +# -- Node Affinity +affinity: {} + +# -- Define which Nodes the Pods are scheduled on. +podLabels: {} + +# Logging resources configuration. +logging: + + # -- Logging resources are disabled by default + enabled: false + + # -- Reference to the logging system. Each of the loggingRefs can manage a fluentbit daemonset and a fluentd statefulset. + loggingRef: "" + + # -- Disable configuration check before applying new fluentd configuration. + flowConfigCheckDisabled: false + + # -- Whether to skip invalid Flow and ClusterFlow resources + skipInvalidResources: false + + # -- Override generated config. This is a raw configuration string for troubleshooting purposes. + flowConfigOverride: "" + + # -- Flag to disable fluentbit completely + fluentbitDisabled: false + # -- Fluent-bit configurations https://kube-logging.github.io/docs/configuration/crds/v1beta1/fluentbit_types/ + fluentbit: {} + + # -- Flag to disable fluentd completely + fluentdDisabled: false + # -- Fluentd configurations https://kube-logging.github.io/docs/configuration/crds/v1beta1/fluentd_types/ + fluentd: {} + # 20Gi persistent storage is configured for fluentd by default. + # Here is an example, on how to override it: + # bufferStorageVolume: + # pvc: + # spec: + # accessModes: + # - ReadWriteOnce + # resources: + # requests: + # storage: 40Gi + + # -- Syslog-NG statefulset configuration + syslogNG: {} + + # -- Default flow for unmatched logs. This Flow configuration collects all logs that didn’t match any other Flow. + defaultFlow: {} + + # -- GlobalOutput name to flush ERROR events to + errorOutputRef: "" + + # -- Global filters to apply on logs before any match or filter mechanism. + globalFilters: [] + + # -- Limit namespaces to watch Flow and Output custom resources. + watchNamespaces: [] + + # -- Limit namespaces to watch Flow and Output custom resources. + watchNamespaceSelector: {} + + # -- Cluster domain name to be used when templating URLs to services + clusterDomain: "cluster.local." + + # -- Namespace for cluster wide configuration resources like ClusterFlow and ClusterOutput. This should be a protected namespace from regular users. Resources like fluentbit and fluentd will run in this namespace as well. + controlNamespace: "" + + # -- Allow configuration of cluster resources from any namespace. Mutually exclusive with ControlNamespace restriction of Cluster resources + allowClusterResourcesFromAllNamespaces: false + + # -- NodeAgent Configuration + nodeAgents: {} + # - name: win-agent + # profile: windows + # nodeAgentFluentbit: + # daemonSet: + # spec: + # template: + # spec: + # containers: + # - image: banzaicloud/fluentbit:1.9.5 + # name: fluent-bit + # tls: + # enabled: false + # - name: linux-agent + # profile: linux + # nodeAgentFluentbit: + # metrics: + # prometheusAnnotations: true + # serviceMonitor: false + # tls: + # enabled: false + + # -- configCheck provides possibility for timeout-based configuration checks https://kube-logging.dev/docs/whats-new/#timeout-based-configuration-checks + configCheck: {} + + # -- EnableRecreateWorkloadOnImmutableFieldChange enables the operator to recreate the fluentbit daemonset and the fluentd statefulset (and possibly other resource in the future) in case there is a change in an immutable field that otherwise couldn’t be managed with a simple update. + enableRecreateWorkloadOnImmutableFieldChange: false + + # -- ClusterFlows to deploy + clusterFlows: [] + + # -- ClusterOutputs to deploy + clusterOutputs: [] + + # Send all pod logs to kafka + # clusterFlows: + # - name: all + # spec: + # match: + # - select: {} + # globalOutputRefs: ["kafka"] + # clusterOutputs: + # - name: kafka + # spec: + # kafka: + # brokers: kafka-headless.kafka.svc.cluster.local:29092 + # format: + # type: json + # default_topic: topic + + # EventTailer config + eventTailer: + enabled: false + name: event-tailer + image: + # -- repository of eventTailer image + repository: + # -- tag of eventTailer image + tag: + # -- pullPolicy of eventTailer image + pullPolicy: + # -- imagePullSecrets of eventTailer image + imagePullSecrets: [] + pvc: + # -- enable pvc for + enabled: false + # -- storage class for event tailer pvc + accessModes: + - ReadWriteOnce + # -- storage class for event tailer pvc + volumeMode: Filesystem + # -- storage for event tailer pvc + storage: 1Gi + # -- storage class for event tailer pvc + storageClassName: + # -- workloadMetaOverrides + workloadMetaOverrides: + # -- workloadOverrides + workloadOverrides: + # -- containerOverrides + containerOverrides: + + hostTailer: + # -- HostTailer + enabled: false + # -- name of HostTailer + name: hosttailer + image: + # -- repository of eventTailer image + repository: + # -- tag of eventTailer image + tag: + # -- pullPolicy of eventTailer image + pullPolicy: + # -- imagePullSecrets of eventTailer image + imagePullSecrets: [] + # -- workloadMetaOverrides of HostTailer + workloadMetaOverrides: + # -- workloadOverrides of HostTailer + workloadOverrides: + # -- configure fileTailers of HostTailer + # example: + # - name: sample-file + # path: /var/log/sample-file + # disabled: false + # buffer_max_size: + # buffer_chunk_size: + # skip_long_lines: + # read_from_head: false + # containerOverrides: + # image: + fileTailers: [] + # -- configure systemdTailers of HostTailer + # example: + # - name: system-sample + # disabled: false + # systemdFilter: kubelet.service + # maxEntries: 20 + # containerOverrides: + # image: + systemdTailers: [] + +testReceiver: + enabled: false + image: fluent/fluent-bit + pullPolicy: IfNotPresent + port: 8080 + # args: ["-i", "http", "-p", "port=8080", "-o", "stdout"] + # resources: + # limits: + # cpu: 100m + # memory: 50Mi + # requests: + # cpu: 20m + # memory: 25Mi + + # Service definition for query http service + service: + type: ClusterIP + clusterIP: None + # Annotations to query http service + annotations: {} + # Labels to query http service + labels: {} + +# Logging CR specific serviceAccount annotations +loggingServiceAccountAnnotations: {} +## Syntax ## +# : +# : +# +## Example ## +# +# root: +# eks.amazonaws.com/role-arn: +# +## Result - added to the Logging resource ## +# +# spec: +# fluentd: +# serviceAccount: +# metadata: +# annotations: +# eks.amazonaws.com/role-arn: arn:aws:iam::1234567890:role/my-iam-role +# + +################################### +# Rancher Logging Operator Values # +################################### + +# Enable debug to use fluent-bit images that allow exec +debug: false + +# Disable persistent volumes for buffers +disablePvc: true + +# If your additional logging sources collect logs from systemd configure the systemd log path here +systemdLogPath: "/run/log/journal" + +global: + cattle: + systemDefaultRegistry: "" + # Uncomment the below two lines to either enable or disable Windows logging. If this chart is + # installed via the Rancher UI, it will set this value to "true" if the cluster is a Windows + # cluster. In that scenario, if you would like to disable Windows logging on Windows clusters, + # set the value below to "false". + # windows: + # enabled: true + psp: + enabled: false + + # Change the "dockerRootDirectory" if the default Docker directory has changed. + dockerRootDirectory: "" + + rkeWindowsPathPrefix: "c:\\" + + seLinux: + enabled: false + +images: + config_reloader: + repository: rancher/mirrored-jimmidyson-configmap-reload + tag: v0.4.0 + fluentbit: + repository: rancher/mirrored-fluent-fluent-bit + tag: 2.2.0 + nodeagent_fluentbit: + os: "windows" + repository: rancher/fluent-bit + tag: 2.2.0 + fluentbit_debug: + repository: rancher/mirrored-fluent-fluent-bit + tag: 2.2.0-debug + fluentd: + repository: rancher/mirrored-kube-logging-fluentd + tag: v1.16-4.8-full + +additionalLoggingSources: + rke: + enabled: false + fluentbit: + log_level: "info" + mem_buffer_limit: "5MB" + rke2: + enabled: false + stripUnderscores: false + k3s: + enabled: false + container_engine: "systemd" + stripUnderscores: false + aks: + enabled: false + eks: + enabled: false + gke: + enabled: false + kubeAudit: + auditFilename: "" + enabled: false + pathPrefix: "" + fluentbit: + logTag: kube-audit + tolerations: + - key: node-role.kubernetes.io/control-plane + value: "true" + effect: NoSchedule + - key: node-role.kubernetes.io/etcd + value: "true" + effect: NoExecute + +# configures node agent options for windows node agents +nodeAgents: + tls: + enabled: false + +# These settings apply to every Logging CR, including vendor Logging CRs enabled in "additionalLoggingSources". +# Changing these affects every Logging CR installed. +fluentd: + bufferStorageVolume: {} + livenessProbe: + tcpSocket: + port: 24240 + initialDelaySeconds: 30 + periodSeconds: 15 + nodeSelector: {} + resources: {} + tolerations: {} + env: [] + logLevel: {} +fluentbit: + inputTail: + Buffer_Chunk_Size: "" + Buffer_Max_Size: "" + Mem_Buf_Limit: "" + Multiline_Flush: "" + Skip_Long_Lines: "" + resources: {} + tolerations: + - key: node-role.kubernetes.io/control-plane + value: "true" + effect: NoSchedule + - key: node-role.kubernetes.io/etcd + value: "true" + effect: NoExecute + filterKubernetes: + Merge_Log: "" + Merge_Log_Key: "" + Merge_Log_Trim: "" + Merge_Parser: "" + +# -- Extra manifests to deploy as an array +extraManifests: [] + # - apiVersion: v1 + # kind: ConfigMap + # metadata: + # labels: + # name: extra-manifest + # data: + # extra-data: "value" + +# DO NOT SET THIS UNLESS YOU KNOW WHAT YOU ARE DOING. +# Setting fields on this object can break rancher logging or cause unexpected behavior. It is intended to be used if you +# need to configure functionality not exposed by rancher logging. It is highly recommended you check the `app-readme.md` +# for the functionality you need before modifying this object. + +# this object will be merged with every logging CR created by this chart. Any fields that collide with fields from the +# settings above will be overridden. Any fields that collide with fields set in the files in `templates/loggings` will +# be ignored. diff --git a/charts/rancher-monitoring-crd/104.1.1+up57.0.3/Chart.yaml b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/Chart.yaml new file mode 100644 index 0000000000..8a8162159b --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/Chart.yaml @@ -0,0 +1,10 @@ +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 +description: Installs the CRDs for rancher-monitoring. +name: rancher-monitoring-crd +type: application +version: 104.1.1+up57.0.3 diff --git a/charts/rancher-monitoring-crd/104.1.1+up57.0.3/README.md b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/README.md new file mode 100644 index 0000000000..e0b63e0268 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/README.md @@ -0,0 +1,24 @@ +# rancher-monitoring-crd +A Rancher chart that installs the CRDs used by rancher-monitoring. + +## How does this chart work? + +This chart marshalls all of the CRD files placed in the `crd-manifest` directory into a ConfigMap that is installed onto a cluster alongside relevant RBAC (ServiceAccount, ClusterRoleBinding, ClusterRole, and PodSecurityPolicy). + +Once the relevant dependent resourcees are installed / upgraded / rolled back, this chart executes a post-install / post-upgrade / post-rollback Job that: +- Patches any existing versions of the CRDs contained within the `crd-manifest` on the cluster to set `spec.preserveUnknownFields=false`; this step is required since, based on [Kubernetes docs](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#field-pruning) and a [known workaround](https://github.com/kubernetes-sigs/controller-tools/issues/476#issuecomment-691519936), such CRDs cannot be upgraded normally from `apiextensions.k8s.io/v1beta1` to `apiextensions.k8s.io/v1`. +- Runs a `kubectl apply` on the CRDs that are contained within the crd-manifest ConfigMap to upgrade CRDs in the cluster + +On an uninstall, this chart executes a separate post-delete Job that: +- Patches any existing versions of the CRDs contained within `crd-manifest` on the cluster to set `metadata.finalizers=[]` +- Runs a `kubectl delete` on the CRDs that are contained within the crd-manifest ConfigMap to clean up the CRDs from the cluster + +Note: If the relevant CRDs already existed in the cluster at the time of install, this chart will absorb ownership of the lifecycle of those CRDs; therefore, on a `helm uninstall`, those CRDs will also be removed from the cluster alongside this chart. + +## Why can't we just place the CRDs in the templates/ directory of the main chart? + +In Helm today, you cannot declare a CRD and declare a resource of that CRD's kind in templates/ without encountering a failure on render. + +## [Helm 3] Why can't we just place the CRDs in the crds/ directory of the main chart? + +The Helm 3 `crds/` directory only supports the installation of CRDs, but does not support the upgrade and removal of CRDs, unlike what this chart facilitiates. \ No newline at end of file diff --git a/charts/rancher-monitoring-crd/104.1.1+up57.0.3/files/crd-manifest.tgz b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/files/crd-manifest.tgz new file mode 100644 index 0000000000000000000000000000000000000000..7c17e986919a4cfee02e2a3aa76140d09e15a6e7 GIT binary patch literal 308563 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%0DeX|hqc5g4>i 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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/104.1.1+up57.0.3/templates/manifest.yaml b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/templates/manifest.yaml new file mode 100644 index 0000000000..8dc9dfb447 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rbac.yaml b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/templates/rbac.yaml new file mode 100644 index 0000000000..a4d498b0fa --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/validate-psp-install.yaml b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/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/104.1.1+up57.0.3/values.yaml b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/values.yaml new file mode 100644 index 0000000000..99e63600c4 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.1+up57.0.3/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/104.1.1+up57.0.3/.editorconfig b/charts/rancher-monitoring/104.1.1+up57.0.3/.editorconfig new file mode 100644 index 0000000000..f5ee2f4610 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/.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/104.1.1+up57.0.3/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/.helmignore new file mode 100644 index 0000000000..9bdbec92b4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/.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/104.1.1+up57.0.3/CHANGELOG.md b/charts/rancher-monitoring/104.1.1+up57.0.3/CHANGELOG.md new file mode 100644 index 0000000000..8178169b91 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/CONTRIBUTING.md b/charts/rancher-monitoring/104.1.1+up57.0.3/CONTRIBUTING.md new file mode 100644 index 0000000000..f6ce2a3235 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/Chart.yaml new file mode 100644 index 0000000000..3342da25cf --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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.26.0-0 < 1.31.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.72.0 +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.19.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: 104.1.1+up57.0.3 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/README.md new file mode 100644 index 0000000000..9baf58bb16 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/README.md @@ -0,0 +1,1080 @@ +# 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 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/104.1.1+up57.0.3/app-README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/app-README.md new file mode 100644 index 0000000000..3920854384 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/.helmignore new file mode 100644 index 0000000000..8cade1318f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/Chart.yaml new file mode 100644 index 0000000000..ff6bcb26aa --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/Chart.yaml @@ -0,0 +1,39 @@ +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.26.0-0 < 1.31.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: 10.4.1 +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.26.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 +name: grafana +sources: +- https://github.com/grafana/grafana +- https://github.com/grafana/helm-charts +type: application +version: 7.3.11 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/README.md new file mode 100644 index 0000000000..0ff07f297d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/README.md @@ -0,0 +1,770 @@ +# 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.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` | +| `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.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.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/104.1.1+up57.0.3/charts/grafana/dashboards/custom-dashboard.json b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/dashboards/custom-dashboard.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/dashboards/custom-dashboard.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/NOTES.txt b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/NOTES.txt new file mode 100644 index 0000000000..d86419fe23 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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 not .Values.persistence.enabled }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Grafana pod is terminated. ##### +################################################################################# +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_config.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_config.tpl new file mode 100644 index 0000000000..19df19cd2a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_config.tpl @@ -0,0 +1,171 @@ +{{/* + 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 }}' + {{- 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/104.1.1+up57.0.3/charts/grafana/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_helpers.tpl new file mode 100644 index 0000000000..68d2d815d8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/_pod.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_pod.tpl new file mode 100644 index 0000000000..2ebf7d5f10 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/_pod.tpl @@ -0,0 +1,1296 @@ +{{- 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 }} + {{- 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.datasources.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 }} + {{- 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/104.1.1+up57.0.3/charts/grafana/templates/clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/clusterrole.yaml new file mode 100644 index 0000000000..3af4b62b63 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..bda9431a2c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/configSecret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/configSecret.yaml new file mode 100644 index 0000000000..55574b9bbc --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/configmap-dashboard-provider.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/configmap-dashboard-provider.yaml new file mode 100644 index 0000000000..b412c4d1f0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/configmap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/configmap.yaml new file mode 100644 index 0000000000..7d7428be51 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/configmap.yaml @@ -0,0 +1,15 @@ +{{- if .Values.createConfigmap }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + {{- include "grafana.configData" . | nindent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/dashboards-json-configmap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/dashboards-json-configmap.yaml new file mode 100644 index 0000000000..b96ce72026 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/deployment.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/deployment.yaml new file mode 100644 index 0000000000..46c016faa3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/extra-manifests.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/extra-manifests.yaml new file mode 100644 index 0000000000..a9bb3b6ba8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/headless-service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/headless-service.yaml new file mode 100644 index 0000000000..3028589d32 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/hpa.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/hpa.yaml new file mode 100644 index 0000000000..46bbcb49a2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-deployment.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-deployment.yaml new file mode 100644 index 0000000000..28231b803e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-deployment.yaml @@ -0,0 +1,131 @@ +{{ 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 + {{- 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: {} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-hpa.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-hpa.yaml new file mode 100644 index 0000000000..b0f0059b79 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-network-policy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-network-policy.yaml new file mode 100644 index 0000000000..d1a0eb313d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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: + 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/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-service.yaml new file mode 100644 index 0000000000..f8da127cf8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/image-renderer-servicemonitor.yaml new file mode 100644 index 0000000000..5d9f09d266 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/ingress.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/ingress.yaml new file mode 100644 index 0000000000..b2ffd81095 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/networkpolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/networkpolicy.yaml new file mode 100644 index 0000000000..4cd3ed6976 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/nginx-config.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/nginx-config.yaml new file mode 100644 index 0000000000..557471f6ff --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/poddisruptionbudget.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..05251214ac --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/podsecuritypolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000000..973caccd57 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/podsecuritypolicy.yaml @@ -0,0 +1,45 @@ +{{- if and (or .Values.global.cattle.psp.enabled .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/104.1.1+up57.0.3/charts/grafana/templates/pvc.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/pvc.yaml new file mode 100644 index 0000000000..c9b234305f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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 (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/104.1.1+up57.0.3/charts/grafana/templates/role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/role.yaml new file mode 100644 index 0000000000..469b6f4e6c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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 (or .Values.global.cattle.psp.enabled .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 (or .Values.global.cattle.psp.enabled .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/104.1.1+up57.0.3/charts/grafana/templates/rolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/rolebinding.yaml new file mode 100644 index 0000000000..58f77c6b0b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/secret-env.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/secret-env.yaml new file mode 100644 index 0000000000..eb14aac707 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/secret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/secret.yaml new file mode 100644 index 0000000000..fd2ca50f4b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/service.yaml new file mode 100644 index 0000000000..e9396a15c6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/service.yaml @@ -0,0 +1,61 @@ +{{- 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 }} + {{- 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/104.1.1+up57.0.3/charts/grafana/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/serviceaccount.yaml new file mode 100644 index 0000000000..ffca0717ae --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/servicemonitor.yaml new file mode 100644 index 0000000000..b321b1269c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/servicemonitor.yaml @@ -0,0 +1,68 @@ +{{- 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 }} + {{- if .Values.serviceMonitor.relabelings }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- 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/104.1.1+up57.0.3/charts/grafana/templates/statefulset.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/statefulset.yaml new file mode 100644 index 0000000000..49278083e8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/tests/test-configmap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-configmap.yaml new file mode 100644 index 0000000000..01c96c9243 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/tests/test-podsecuritypolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-podsecuritypolicy.yaml new file mode 100644 index 0000000000..70a0a884c9 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-podsecuritypolicy.yaml @@ -0,0 +1,32 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled (or .Values.global.cattle.psp.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/104.1.1+up57.0.3/charts/grafana/templates/tests/test-role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-role.yaml new file mode 100644 index 0000000000..976418b137 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-role.yaml @@ -0,0 +1,17 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled (or .Values.global.cattle.psp.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/104.1.1+up57.0.3/charts/grafana/templates/tests/test-rolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-rolebinding.yaml new file mode 100644 index 0000000000..509566eccd --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled (or .Values.global.cattle.psp.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/104.1.1+up57.0.3/charts/grafana/templates/tests/test-serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test-serviceaccount.yaml new file mode 100644 index 0000000000..38fba3596a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/templates/tests/test.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/templates/tests/test.yaml new file mode 100644 index 0000000000..83aaa185c2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/grafana/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/values.yaml new file mode 100644 index 0000000000..2bb62aec39 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/grafana/values.yaml @@ -0,0 +1,1315 @@ +global: + cattle: + psp: + enabled: false + 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 tempalted. + # 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: 10.3.3 + 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: 7.85.0 + 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: {} + +## 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 + 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 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: 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: {} + + ## 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 + +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.26.1 + 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: {} + # 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: '' + # 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: {} + envValueFrom: {} + # 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.10.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" + +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/104.1.1+up57.0.3/charts/hardenedKubelet/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/Chart.yaml new file mode 100644 index 0000000000..acd648a5b4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: hardenedKubelet +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedKubelet/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedKubelet/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/Chart.yaml new file mode 100644 index 0000000000..068932bacb --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: hardenedNodeExporter +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/hardenedNodeExporter/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/hardenedNodeExporter/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/Chart.yaml new file mode 100644 index 0000000000..275e02e5dc --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: k3sServer +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/k3sServer/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/k3sServer/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/Chart.yaml new file mode 100644 index 0000000000..002a6a180d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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.26.0-0 < 1.31.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.10.1 +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.16.4 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/README.md new file mode 100644 index 0000000000..843be89e69 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/NOTES.txt b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/NOTES.txt new file mode 100644 index 0000000000..3589c24ec3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/_helpers.tpl new file mode 100644 index 0000000000..ed277fbb53 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000000..025cd47a88 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..cf9f628d04 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/crs-configmap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/crs-configmap.yaml new file mode 100644 index 0000000000..d38a75a51d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/deployment.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/deployment.yaml new file mode 100644 index 0000000000..03158eb948 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/deployment.yaml @@ -0,0 +1,314 @@ +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: + 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 }} + {{- if .Values.resources }} + resources: +{{ toYaml .Values.resources | indent 10 }} +{{- end }} +{{- 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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/extra-manifests.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/extra-manifests.yaml new file mode 100644 index 0000000000..567f7bf329 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/kubeconfig-secret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/kubeconfig-secret.yaml new file mode 100644 index 0000000000..6af0084502 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/networkpolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/networkpolicy.yaml new file mode 100644 index 0000000000..309b38ec54 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/pdb.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/pdb.yaml new file mode 100644 index 0000000000..3771b511de --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/podsecuritypolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000000..d9d944d740 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/podsecuritypolicy.yaml @@ -0,0 +1,39 @@ +{{- if and .Values.rbac.create (and (or .Values.global.cattle.psp.enabled .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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrole.yaml new file mode 100644 index 0000000000..c69e01a716 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.rbac.create (and (or .Values.global.cattle.psp.enabled .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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..df81c49028 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.rbac.create (and (or .Values.global.cattle.psp.enabled .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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/rbac-configmap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/rbac-configmap.yaml new file mode 100644 index 0000000000..671dc9d660 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/role.yaml new file mode 100644 index 0000000000..0170878376 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/rolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/rolebinding.yaml new file mode 100644 index 0000000000..330651b73f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/service.yaml new file mode 100644 index 0000000000..6c486a662a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/service.yaml @@ -0,0 +1,49 @@ +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 }}" + 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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/serviceaccount.yaml new file mode 100644 index 0000000000..38a93b31d1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/servicemonitor.yaml new file mode 100644 index 0000000000..01ec44e067 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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 .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.interval }} + {{- end }} + {{- if .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.proxyUrl}} + {{- end }} + {{- if .Values.prometheus.monitor.enableHttp2 }} + enableHttp2: {{ .Values.prometheus.monitor.enableHttp2}} + {{- end }} + {{- if .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + metricRelabelings: + {{- if .Values.prometheus.monitor.metricRelabelings }} + {{- toYaml .Values.prometheus.monitor.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.monitor.relabelings }} + relabelings: + {{- toYaml .Values.prometheus.monitor.relabelings | nindent 8 }} + {{- end }} + {{- if .Values.prometheus.monitor.scheme }} + scheme: {{ .Values.prometheus.monitor.scheme }} + {{- end }} + {{- if .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml .Values.prometheus.monitor.tlsConfig | nindent 8 }} + {{- end }} + {{- if .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.monitor.bearerTokenFile }} + {{- end }} + {{- with .Values.prometheus.monitor.bearerTokenSecret }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.selfMonitor.enabled }} + - port: metrics + {{- if .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.interval }} + {{- end }} + {{- if .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.proxyUrl}} + {{- end }} + {{- if .Values.prometheus.monitor.enableHttp2 }} + enableHttp2: {{ .Values.prometheus.monitor.enableHttp2}} + {{- end }} + {{- if .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml .Values.prometheus.monitor.relabelings | nindent 8 }} + {{- end }} + {{- if .Values.prometheus.monitor.scheme }} + scheme: {{ .Values.prometheus.monitor.scheme }} + {{- end }} + {{- if .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml .Values.prometheus.monitor.tlsConfig | nindent 8 }} + {{- end }} + {{- if .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.monitor.bearerTokenFile }} + {{- end }} + {{- with .Values.prometheus.monitor.bearerTokenSecret }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-role.yaml new file mode 100644 index 0000000000..489de147c1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml new file mode 100644 index 0000000000..73b37a4f64 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml new file mode 100644 index 0000000000..f46305b517 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kube-state-metrics/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/values.yaml new file mode 100644 index 0000000000..bc8ee28fda --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kube-state-metrics/values.yaml @@ -0,0 +1,491 @@ +# Default values for kube-state-metrics. +prometheusScrape: true +image: + registry: docker.io + repository: rancher/mirrored-kube-state-metrics-kube-state-metrics + tag: v2.10.1 + sha: "" + pullPolicy: IfNotPresent + +imagePullSecrets: [] +# - name: "image-pull-secret" + +global: + cattle: + psp: + enabled: false + 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: [] + +service: + port: 8080 + # Default to clusterIP for backward compatibility + type: ClusterIP + 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-kube-rbac-proxy + tag: v0.14.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: {} + +prometheus: + monitor: + enabled: false + annotations: {} + additionalLabels: {} + namespace: "" + namespaceSelector: [] + jobLabel: "" + targetLabels: [] + podTargetLabels: [] + 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 + scrapeTimeout: "" + proxyUrl: "" + ## Whether to enable HTTP2 for servicemonitor + # enableHttp2: false + selectorOverride: {} + 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: + 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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/Chart.yaml new file mode 100644 index 0000000000..ad9fba247a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: kubeAdmControllerManager +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmControllerManager/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/Chart.yaml new file mode 100644 index 0000000000..d144d3ee2a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: kubeAdmEtcd +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmEtcd/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmEtcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/Chart.yaml new file mode 100644 index 0000000000..a1222c4feb --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: kubeAdmProxy +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmProxy/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmProxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/Chart.yaml new file mode 100644 index 0000000000..78a44159a9 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: kubeAdmScheduler +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/kubeAdmScheduler/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/kubeAdmScheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/Chart.yaml new file mode 100644 index 0000000000..d067725a17 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/Chart.yaml @@ -0,0 +1,28 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.10.0 +description: A Helm chart for k8s prometheus adapter +home: https://github.com/kubernetes-sigs/prometheus-adapter +keywords: +- hpa +- metrics +- prometheus +- adapter +kubeVersion: '>=1.26.0-0' +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.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/README.md new file mode 100644 index 0000000000..d77bb0c920 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/NOTES.txt b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/NOTES.txt new file mode 100644 index 0000000000..b7b9b99322 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/_helpers.tpl new file mode 100644 index 0000000000..edbb829b2b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/certmanager.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/certmanager.yaml new file mode 100644 index 0000000000..4e32c964c6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml new file mode 100644 index 0000000000..6701e6ba08 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml new file mode 100644 index 0000000000..67efd2aa2f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml new file mode 100644 index 0000000000..2c690a03cc --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/configmap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/configmap.yaml new file mode 100644 index 0000000000..17f415d970 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml new file mode 100644 index 0000000000..8b7b4e555e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml new file mode 100644 index 0000000000..0cc6920836 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml new file mode 100644 index 0000000000..4aa15ffe99 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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: ["*"] + verbs: ["*"] +{{- end -}} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/deployment.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/deployment.yaml new file mode 100644 index 0000000000..a7ea3310a0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/deployment.yaml @@ -0,0 +1,143 @@ +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}} + containers: + - name: {{ .Chart.Name }} + image: "{{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }}" + 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 }} + {{- if .Values.resources }} + resources: + {{- toYaml .Values.resources | nindent 10 }} + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: + {{ toYaml . | indent 8 }} + {{- 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 }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.nodeSelector }} +{{- toYaml .Values.nodeSelector | nindent 8 }} +{{- end }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + topologySpreadConstraints: + {{- toYaml .Values.topologySpreadConstraints | nindent 8 }} + priorityClassName: {{ .Values.priorityClassName }} + {{- 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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml new file mode 100644 index 0000000000..21339af128 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml new file mode 100644 index 0000000000..05547bd323 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml new file mode 100644 index 0000000000..212ea78b25 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml @@ -0,0 +1,21 @@ +{{- 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: + - "*" + verbs: + - list + - get + - watch +{{- end -}} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/pdb.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/pdb.yaml new file mode 100644 index 0000000000..205761a9f1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/psp.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/psp.yaml new file mode 100644 index 0000000000..fded5a7491 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/psp.yaml @@ -0,0 +1,66 @@ +{{- if and (or .Values.global.cattle.psp.enabled .Values.psp.create) (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "k8s-prometheus-adapter.fullname" . }} + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | 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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml new file mode 100644 index 0000000000..0cc9fff6a2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml new file mode 100644 index 0000000000..3c247e48d2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml new file mode 100644 index 0000000000..73d8953046 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml new file mode 100644 index 0000000000..d3c77c1c65 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml @@ -0,0 +1,21 @@ +{{- if .Values.rbac.create -}} +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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/secret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/secret.yaml new file mode 100644 index 0000000000..3e7e8887bd --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/service.yaml new file mode 100644 index 0000000000..ddac37cfa1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/service.yaml @@ -0,0 +1,27 @@ +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: + ports: + - port: {{ .Values.service.port }} + 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/104.1.1+up57.0.3/charts/prometheus-adapter/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/templates/serviceaccount.yaml new file mode 100644 index 0000000000..30a169ae0e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-adapter/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/values.yaml new file mode 100644 index 0000000000..a1445a23f1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-adapter/values.yaml @@ -0,0 +1,277 @@ +# Default values for k8s-prometheus-adapter.. +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + +affinity: {} + +topologySpreadConstraints: [] + +image: + repository: rancher/mirrored-prometheus-adapter-prometheus-adapter + 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 + +psp: + # Specifies whether PSP resources should be created + create: false + +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 + +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 + +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 + +# 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: 43800h + certDuration: 8760h diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/Chart.yaml new file mode 100644 index 0000000000..9130cbcc91 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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.7.0 +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.30.3 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/README.md new file mode 100644 index 0000000000..149b982267 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/README.md @@ -0,0 +1,97 @@ + +# 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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/NOTES.txt b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/NOTES.txt new file mode 100644 index 0000000000..8c5391f1f7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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:{{ .Values.service.port }} to use your application" + kubectl port-forward --namespace {{ template "prometheus-node-exporter.namespace" . }} $POD_NAME {{ .Values.service.port }} +{{- 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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/_helpers.tpl new file mode 100644 index 0000000000..72a6db45a1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/clusterrole.yaml new file mode 100644 index 0000000000..c256dba73d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..653305ad9e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/daemonset.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/daemonset.yaml new file mode 100644 index 0000000000..48d274f1b1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/daemonset.yaml @@ -0,0 +1,309 @@ +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=8888 + - --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: 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 | 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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/endpoints.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/endpoints.yaml new file mode 100644 index 0000000000..56b695203a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/extra-manifests.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/extra-manifests.yaml new file mode 100644 index 0000000000..2b21b71062 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl . $ }} +{{ end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/networkpolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/networkpolicy.yaml new file mode 100644 index 0000000000..825722729d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/podmonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/podmonitor.yaml new file mode 100644 index 0000000000..f88da6a34e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml new file mode 100644 index 0000000000..750564b654 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if and (or .Values.global.cattle.psp.enable (.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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..160f2bbf7a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and (or .Values.global.cattle.psp.enable (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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp.yaml new file mode 100644 index 0000000000..f3b52e1120 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/psp.yaml @@ -0,0 +1,49 @@ +{{- if and (or .Values.global.cattle.psp.enable (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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/rbac-configmap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/rbac-configmap.yaml new file mode 100644 index 0000000000..814e110337 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/service.yaml new file mode 100644 index 0000000000..a065e46e39 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/service.yaml @@ -0,0 +1,29 @@ +{{- 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 }} + 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.targetPort }} + protocol: TCP + name: {{ .Values.service.portName }} + selector: + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/serviceaccount.yaml new file mode 100644 index 0000000000..5c3348c09b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- 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 }} +{{- 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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/servicemonitor.yaml new file mode 100644 index 0000000000..6d6e440473 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml new file mode 100644 index 0000000000..2c2705f872 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/prometheus-node-exporter/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/values.yaml new file mode 100644 index 0000000000..b9f2f7ab87 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/prometheus-node-exporter/values.yaml @@ -0,0 +1,530 @@ +# 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.7.0 + 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: + psp: + enable: true + 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: "docker.io" + +# 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-kube-rbac-proxy + tag: v0.15.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 + + 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 + port: 9796 + targetPort: 9796 + nodePort: + portName: metrics + listenOnAllInterfaces: true + annotations: + prometheus.io/scrape: "true" + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + +# 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 + 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/104.1.1+up57.0.3/charts/rke2ControllerManager/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/Chart.yaml new file mode 100644 index 0000000000..dbf4d0b815 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rke2ControllerManager +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2ControllerManager/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2ControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/Chart.yaml new file mode 100644 index 0000000000..87495a6a6b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rke2Etcd +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Etcd/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Etcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/Chart.yaml new file mode 100644 index 0000000000..4bce6d41ea --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rke2IngressNginx +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2IngressNginx/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2IngressNginx/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/Chart.yaml new file mode 100644 index 0000000000..0a316e05c7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rke2Proxy +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Proxy/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Proxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/Chart.yaml new file mode 100644 index 0000000000..fa6aa5ac66 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rke2Scheduler +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rke2Scheduler/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rke2Scheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/Chart.yaml new file mode 100644 index 0000000000..df00a46b66 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rkeControllerManager +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeControllerManager/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/Chart.yaml new file mode 100644 index 0000000000..96b33f0bc8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rkeEtcd +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeEtcd/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeEtcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/Chart.yaml new file mode 100644 index 0000000000..bc49bcefd2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rkeIngressNginx +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeIngressNginx/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeIngressNginx/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/Chart.yaml new file mode 100644 index 0000000000..18eac324d4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rkeProxy +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeProxy/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeProxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/Chart.yaml new file mode 100644 index 0000000000..8c53b63bcc --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.26.0-0 < 1.31.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.26.0-0' +name: rkeScheduler +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/rkeScheduler/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/rkeScheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/.helmignore b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/Chart.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/Chart.yaml new file mode 100644 index 0000000000..784bb0ec7e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/README.md b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/README.md new file mode 100644 index 0000000000..1da1c64e12 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/scripts/configure-firewall.ps1 b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/scripts/configure-firewall.ps1 new file mode 100644 index 0000000000..9cbed7112d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/_helpers.tpl new file mode 100644 index 0000000000..c9a5d6db8c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/templates/config.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/config.yaml new file mode 100644 index 0000000000..25f1fa69c2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/templates/daemonset.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/daemonset.yaml new file mode 100644 index 0000000000..be7feb3ed1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/templates/podmonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/podmonitor.yaml new file mode 100644 index 0000000000..bbb6c39340 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/templates/scriptConfig.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/scriptConfig.yaml new file mode 100644 index 0000000000..f514c8161a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/templates/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/service.yaml new file mode 100644 index 0000000000..267b796f63 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/serviceaccount.yaml new file mode 100644 index 0000000000..14c1c46807 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/templates/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/templates/servicemonitor.yaml new file mode 100644 index 0000000000..2effc07758 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/charts/windowsExporter/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/charts/windowsExporter/values.yaml new file mode 100644 index 0000000000..04569505d6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/ingress-nginx/nginx.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/ingress-nginx/nginx.json new file mode 100644 index 0000000000..565352235a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/ingress-nginx/request-handling-performance.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/ingress-nginx/request-handling-performance.json new file mode 100644 index 0000000000..156e33123d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/cluster/rancher-cluster-nodes.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/cluster/rancher-cluster-nodes.json new file mode 100644 index 0000000000..1d4943501b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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_load5 OR avg_over_time(windows_system_processor_queue_length[5m])) by (instance)", + "interval": "", + "legendFormat": "Load[5m] ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(node_load1 OR avg_over_time(windows_system_processor_queue_length[1m])) by (instance)", + "interval": "", + "legendFormat": "Load[1m] ({{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/104.1.1+up57.0.3/files/rancher/cluster/rancher-cluster.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/cluster/rancher-cluster.json new file mode 100644 index 0000000000..24385a237a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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_load5 OR avg_over_time(windows_system_processor_queue_length[5m]))", + "interval": "", + "legendFormat": "Load[5m]", + "refId": "A" + }, + { + "expr": "sum(node_load1 OR avg_over_time(windows_system_processor_queue_length[1m]))", + "interval": "", + "legendFormat": "Load[1m]", + "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/104.1.1+up57.0.3/files/rancher/fleet/bundle.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/bundle.json new file mode 100644 index 0000000000..698f48aeed --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/fleet/bundledeployment.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/bundledeployment.json new file mode 100644 index 0000000000..c81f7a6212 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/fleet/cluster.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/cluster.json new file mode 100644 index 0000000000..73bdea4834 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/fleet/clustergroup.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/clustergroup.json new file mode 100644 index 0000000000..ce3df87b21 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/fleet/controller-runtime.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/controller-runtime.json new file mode 100644 index 0000000000..23a81f2a8c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/fleet/gitrepo.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/fleet/gitrepo.json new file mode 100644 index 0000000000..1a50c2937d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/home/rancher-default-home.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/home/rancher-default-home.json new file mode 100644 index 0000000000..3fce207561 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/k8s/rancher-etcd-nodes.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/k8s/rancher-etcd-nodes.json new file mode 100644 index 0000000000..8af4b81ce0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/k8s/rancher-etcd.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/k8s/rancher-etcd.json new file mode 100644 index 0000000000..0c058cafb9 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/k8s/rancher-k8s-components-nodes.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/k8s/rancher-k8s-components-nodes.json new file mode 100644 index 0000000000..b31358eaaf --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/k8s/rancher-k8s-components.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/k8s/rancher-k8s-components.json new file mode 100644 index 0000000000..44cf97f9fd --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/nodes/rancher-node-detail.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/nodes/rancher-node-detail.json new file mode 100644 index 0000000000..920fb94cf7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/nodes/rancher-node.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/nodes/rancher-node.json new file mode 100644 index 0000000000..367df3cc9d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/performance/performance-debugging.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/performance/performance-debugging.json new file mode 100644 index 0000000000..454bc39390 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/pods/rancher-pod-containers.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/pods/rancher-pod-containers.json new file mode 100644 index 0000000000..cf78a2204c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/pods/rancher-pod.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/pods/rancher-pod.json new file mode 100644 index 0000000000..4859eccc74 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/workloads/rancher-workload-pods.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/workloads/rancher-workload-pods.json new file mode 100644 index 0000000000..92c0d24a6e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/rancher/workloads/rancher-workload.json b/charts/rancher-monitoring/104.1.1+up57.0.3/files/rancher/workloads/rancher-workload.json new file mode 100644 index 0000000000..9f5317c2f0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/files/upgrade/scripts/delete-workloads-with-old-labels.sh b/charts/rancher-monitoring/104.1.1+up57.0.3/files/upgrade/scripts/delete-workloads-with-old-labels.sh new file mode 100644 index 0000000000..89431e7132 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/NOTES.txt b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/NOTES.txt new file mode 100644 index 0000000000..371f3ae398 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/_helpers.tpl new file mode 100644 index 0000000000..d2207dd90d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/_helpers.tpl @@ -0,0 +1,459 @@ +# 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 }} + +{{/* Fullname suffixed with thanos-ruler */}} +{{- define "kube-prometheus-stack.thanosRuler.fullname" -}} +{{- printf "%s-thanos-ruler" (include "kube-prometheus-stack.fullname" .) -}} +{{- 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/104.1.1+up57.0.3/templates/alertmanager/alertmanager.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/alertmanager.yaml new file mode 100644 index 0000000000..19044054ac --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/alertmanager.yaml @@ -0,0 +1,191 @@ +{{- 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: {{ .Values.alertmanager.alertmanagerSpec.image.tag }} + {{- 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 }} +{{- 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/104.1.1+up57.0.3/templates/alertmanager/extrasecret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/extrasecret.yaml new file mode 100644 index 0000000000..ecd8f47021 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/alertmanager/ingress.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/ingress.yaml new file mode 100644 index 0000000000..be9f5aa279 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/alertmanager/ingressperreplica.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/ingressperreplica.yaml new file mode 100644 index 0000000000..b2e00a4162 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/alertmanager/podDisruptionBudget.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/podDisruptionBudget.yaml new file mode 100644 index 0000000000..b183403125 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/alertmanager/psp-role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp-role.yaml new file mode 100644 index 0000000000..8810e93ded --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp-role.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.alertmanager.enabled (or .Values.global.cattle.psp.enabled (and .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/104.1.1+up57.0.3/templates/alertmanager/psp-rolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp-rolebinding.yaml new file mode 100644 index 0000000000..794f4ad178 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp-rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.alertmanager.enabled (or .Values.global.cattle.psp.enabled (and .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/104.1.1+up57.0.3/templates/alertmanager/psp.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp.yaml new file mode 100644 index 0000000000..07b616b5cb --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/psp.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.alertmanager.enabled (or .Values.global.cattle.psp.enabled (and .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/104.1.1+up57.0.3/templates/alertmanager/secret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/secret.yaml new file mode 100644 index 0000000000..d2fe84a7bf --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/secret.yaml @@ -0,0 +1,35 @@ +{{- 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 }} +{{ 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/104.1.1+up57.0.3/templates/alertmanager/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/service.yaml new file mode 100644 index 0000000000..373de328a5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/service.yaml @@ -0,0 +1,68 @@ +{{- $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 }}" +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/serviceaccount.yaml new file mode 100644 index 0000000000..745ced8bde --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/alertmanager/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/servicemonitor.yaml new file mode 100644 index 0000000000..6233690019 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/alertmanager/serviceperreplica.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/alertmanager/serviceperreplica.yaml new file mode 100644 index 0000000000..75a13bdf97 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/core-dns/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/core-dns/service.yaml new file mode 100644 index 0000000000..b8618f7558 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/core-dns/service.yaml @@ -0,0 +1,24 @@ +{{- 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 + 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/104.1.1+up57.0.3/templates/exporters/core-dns/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/core-dns/servicemonitor.yaml new file mode 100644 index 0000000000..dc15a06937 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-api-server/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-api-server/servicemonitor.yaml new file mode 100644 index 0000000000..66e777632e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/endpoints.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/endpoints.yaml new file mode 100644 index 0000000000..6a6afa6412 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/service.yaml new file mode 100644 index 0000000000..43b1a976d5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/service.yaml @@ -0,0 +1,29 @@ +{{- 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 + 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/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-controller-manager/servicemonitor.yaml new file mode 100644 index 0000000000..7ed3baa65f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-dns/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-dns/service.yaml new file mode 100644 index 0000000000..81b2c9930c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-dns/service.yaml @@ -0,0 +1,28 @@ +{{- 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 + 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/104.1.1+up57.0.3/templates/exporters/kube-dns/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-dns/servicemonitor.yaml new file mode 100644 index 0000000000..9fa41b575f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-etcd/endpoints.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-etcd/endpoints.yaml new file mode 100644 index 0000000000..e366447577 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-etcd/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-etcd/service.yaml new file mode 100644 index 0000000000..d07d4f35e3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-etcd/service.yaml @@ -0,0 +1,27 @@ +{{- 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 + 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/104.1.1+up57.0.3/templates/exporters/kube-etcd/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-etcd/servicemonitor.yaml new file mode 100644 index 0000000000..26fdbdbed3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-proxy/endpoints.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-proxy/endpoints.yaml new file mode 100644 index 0000000000..8613e62425 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-proxy/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-proxy/service.yaml new file mode 100644 index 0000000000..8ccb2210d7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-proxy/service.yaml @@ -0,0 +1,27 @@ +{{- 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 + 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/104.1.1+up57.0.3/templates/exporters/kube-proxy/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-proxy/servicemonitor.yaml new file mode 100644 index 0000000000..24b0ab2001 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-scheduler/endpoints.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-scheduler/endpoints.yaml new file mode 100644 index 0000000000..6236b42f10 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-scheduler/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-scheduler/service.yaml new file mode 100644 index 0000000000..90b3a800a4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-scheduler/service.yaml @@ -0,0 +1,29 @@ +{{- 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 + 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/104.1.1+up57.0.3/templates/exporters/kube-scheduler/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-scheduler/servicemonitor.yaml new file mode 100644 index 0000000000..b17c4f1d47 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kube-state-metrics/validate.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kube-state-metrics/validate.yaml new file mode 100644 index 0000000000..9211b3d771 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/kubelet/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/kubelet/servicemonitor.yaml new file mode 100644 index 0000000000..f570fbfdbc --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/exporters/node-exporter/validate.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/exporters/node-exporter/validate.yaml new file mode 100644 index 0000000000..bdc73d6165 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/extra-objects.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/extra-objects.yaml new file mode 100644 index 0000000000..567f7bf329 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/extra-objects.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/configmap-dashboards.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/configmap-dashboards.yaml new file mode 100644 index 0000000000..e719009ffe --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/grafana/configmaps-datasources.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/configmaps-datasources.yaml new file mode 100644 index 0000000000..718020d4f6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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: Prometheus + 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: Prometheus-{{ . }} + 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: Alertmanager + 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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/alertmanager-overview.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/alertmanager-overview.yaml new file mode 100644 index 0000000000..dfc26d7ecd --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/apiserver.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/apiserver.yaml new file mode 100644 index 0000000000..bd1048b567 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/apiserver.yaml @@ -0,0 +1,1772 @@ +{{- /* +Generated from 'apiserver' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/cluster-total.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/cluster-total.yaml new file mode 100644 index 0000000000..f4be0bbd45 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/controller-manager.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/controller-manager.yaml new file mode 100644 index 0000000000..8d420d7a4f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/etcd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/etcd.yaml new file mode 100644 index 0000000000..0eeedc6299 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/grafana-overview.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/grafana-overview.yaml new file mode 100644 index 0000000000..d2609140cf --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-coredns.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-coredns.yaml new file mode 100644 index 0000000000..7ecca76f23 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml new file mode 100644 index 0000000000..93ee57db93 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml new file mode 100644 index 0000000000..9c295831a5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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: |- + {{`{"annotations":{"list":[]},"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"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","format":"time_series","instant":true,"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(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"cpu\"})","format":"time_series","instant":true,"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(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"cpu\"})","format":"time_series","instant":true,"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) / sum(node_memory_MemTotal_bytes{job=\"node-exporter\"})","format":"time_series","instant":true,"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(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"memory\"})","format":"time_series","instant":true,"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(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"memory\"})","format":"time_series","instant":true,"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":0,"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":2,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":12,"stack":false,"steppedLine":false,"targets":[{"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster)","format":"time_series","legendFormat":"{{cluster}}","legendLink":null}],"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":"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":"Cluster","colorMode":null,"colors":[],"dateFormat":"YYYY-MM-DD HH:mm:ss","decimals":2,"link":true,"linkTargetBlank":false,"linkTooltip":"Drill down","linkUrl":"/d/efa86fd1d0c121a26444b636a3f509a8/k8s-resources-cluster?var-datasource=$datasource&var-cluster=`}}{{ if .Values.grafana.sidecar.dashboards.enableNewTablePanelSyntax }}${__value.text}{{ else }}$__cell{{ end }}{{`","pattern":"cluster","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) by (cluster)","format":"table","instant":true,"legendFormat":"","refId":"A"},{"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true,"legendFormat":"","refId":"B"},{"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,"legendFormat":"","refId":"C"},{"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true,"legendFormat":"","refId":"D"},{"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,"legendFormat":"","refId":"E"}],"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":0,"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":2,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":12,"stack":false,"steppedLine":false,"targets":[{"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster)","format":"time_series","legendFormat":"{{cluster}}","legendLink":null}],"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":"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":"Cluster","colorMode":null,"colors":[],"dateFormat":"YYYY-MM-DD HH:mm:ss","decimals":2,"link":true,"linkTargetBlank":false,"linkTooltip":"Drill down","linkUrl":"/d/efa86fd1d0c121a26444b636a3f509a8/k8s-resources-cluster?var-datasource=$datasource&var-cluster=`}}{{ if .Values.grafana.sidecar.dashboards.enableNewTablePanelSyntax }}${__value.text}{{ else }}$__cell{{ end }}{{`","pattern":"cluster","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_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster)","format":"table","instant":true,"legendFormat":"","refId":"A"},{"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true,"legendFormat":"","refId":"B"},{"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,"legendFormat":"","refId":"C"},{"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true,"legendFormat":"","refId":"D"},{"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,"legendFormat":"","refId":"E"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Requests by Cluster","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"}],"schemaVersion":14,"style":"dark","tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"text":"default","value":"default"},"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"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Multi-Cluster","uid":"b59e6c9f2fcbe2e16d77fc492374cc4f","version":0}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml new file mode 100644 index 0000000000..1c32c9c02e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-node.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-node.yaml new file mode 100644 index 0000000000..e60a42d747 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml new file mode 100644 index 0000000000..80fab51c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml new file mode 100644 index 0000000000..d77170afd8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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: |- + {{`{"__inputs":[],"__requires":[],"annotations":{"list":[]},"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[],"refresh":"","rows":[{"collapse":false,"height":"100px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"format":"percentunit","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":2,"stack":false,"steppedLine":false,"targets":[{"expr":"1 - avg(rate(windows_cpu_time_total{cluster=\"$cluster\", job=\"windows-exporter\", mode=\"idle\"}[1m]))","format":"time_series","instant":true,"refId":"A"}],"thresholds":"70,80","timeFrom":null,"timeShift":null,"title":"CPU Utilisation","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"singlestat","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]},{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"format":"percentunit","id":3,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":2,"stack":false,"steppedLine":false,"targets":[{"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) / sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"})","format":"time_series","instant":true,"refId":"A"}],"thresholds":"70,80","timeFrom":null,"timeShift":null,"title":"CPU Requests Commitment","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"singlestat","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]},{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"format":"percentunit","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":2,"stack":false,"steppedLine":false,"targets":[{"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) / sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"})","format":"time_series","instant":true,"refId":"A"}],"thresholds":"70,80","timeFrom":null,"timeShift":null,"title":"CPU Limits Commitment","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"singlestat","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]},{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"format":"percentunit","id":5,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":2,"stack":false,"steppedLine":false,"targets":[{"expr":"1 - sum(:windows_node_memory_MemFreeCached_bytes:sum{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","format":"time_series","instant":true,"refId":"A"}],"thresholds":"70,80","timeFrom":null,"timeShift":null,"title":"Memory Utilisation","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"singlestat","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]},{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"format":"percentunit","id":6,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":2,"stack":false,"steppedLine":false,"targets":[{"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","format":"time_series","instant":true,"refId":"A"}],"thresholds":"70,80","timeFrom":null,"timeShift":null,"title":"Memory Requests Commitment","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"singlestat","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]},{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"format":"percentunit","id":7,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":2,"stack":false,"steppedLine":false,"targets":[{"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","format":"time_series","instant":true,"refId":"A"}],"thresholds":"70,80","timeFrom":null,"timeShift":null,"title":"Memory Limits Commitment","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"singlestat","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]}],"repeat":null,"repeatIteration":null,"repeatRowId":null,"showTitle":false,"title":"Headlines","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":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":12,"stack":true,"steppedLine":false,"targets":[{"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace)","format":"time_series","legendFormat":"{{namespace}}","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"CPU Usage","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":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":9,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":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":"Namespace","colorMode":null,"colors":[],"dateFormat":"YYYY-MM-DD HH:mm:ss","decimals":2,"link":true,"linkTargetBlank":false,"linkTooltip":"Drill down","linkUrl":"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?var-datasource=$datasource&var-namespace=`}}{{ if .Values.grafana.sidecar.dashboards.enableNewTablePanelSyntax }}${__value.text}{{ else }}$__cell{{ end }}{{`","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(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true,"legendFormat":"","refId":"A"},{"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true,"legendFormat":"","refId":"B"},{"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,"legendFormat":"","refId":"C"},{"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true,"legendFormat":"","refId":"D"},{"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,"legendFormat":"","refId":"E"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"CPU Quota","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":"CPU Quota","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"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":12,"stack":true,"steppedLine":false,"targets":[{"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace)","format":"time_series","legendFormat":"{{namespace}}","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Memory Usage (Private Working Set)","tooltip":{"shared":true,"sort":2,"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":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":11,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":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":"decbytes"},{"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":"decbytes"},{"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":"decbytes"},{"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":"Namespace","colorMode":null,"colors":[],"dateFormat":"YYYY-MM-DD HH:mm:ss","decimals":2,"link":true,"linkTargetBlank":false,"linkTooltip":"Drill down","linkUrl":"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?var-datasource=$datasource&var-namespace=`}}{{ if .Values.grafana.sidecar.dashboards.enableNewTablePanelSyntax }}${__value.text}{{ else }}$__cell{{ end }}{{`","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(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true,"legendFormat":"","refId":"A"},{"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true,"legendFormat":"","refId":"B"},{"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,"legendFormat":"","refId":"C"},{"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true,"legendFormat":"","refId":"D"},{"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,"legendFormat":"","refId":"E"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Requests by Namespace","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":"Memory Requests","titleSize":"h6"}],"schemaVersion":14,"style":"dark","tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"text":"default","value":"default"},"hide":0,"label":null,"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=\"windows-exporter\"}, cluster)","refresh":2,"regex":"","sort":1,"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":"Kubernetes / Compute Resources / Cluster(Windows)","uid":"4d08557fd9391b100730f2494bccac68","version":0}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml new file mode 100644 index 0000000000..13a1fc3abd --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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: |- + {{`{"__inputs":[],"__requires":[],"annotations":{"list":[]},"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[],"refresh":"","rows":[{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":10,"id":2,"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":12,"stack":true,"steppedLine":false,"targets":[{"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"time_series","legendFormat":"{{pod}}","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"CPU Usage","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":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":3,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":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/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?var-datasource=$datasource&var-namespace=$namespace&var-pod=`}}{{ if .Values.grafana.sidecar.dashboards.enableNewTablePanelSyntax }}${__value.text}{{ else }}$__cell{{ end }}{{`","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(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true,"legendFormat":"","refId":"A"},{"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true,"legendFormat":"","refId":"B"},{"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,"legendFormat":"","refId":"C"},{"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true,"legendFormat":"","refId":"D"},{"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,"legendFormat":"","refId":"E"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"CPU Quota","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":"CPU Quota","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":10,"id":4,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":0,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":12,"stack":true,"steppedLine":false,"targets":[{"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"time_series","legendFormat":"{{pod}}","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Memory Usage","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"decbytes","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,"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":"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":"decbytes"},{"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":"decbytes"},{"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":"decbytes"},{"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/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?var-datasource=$datasource&var-namespace=$namespace&var-pod=`}}{{ if .Values.grafana.sidecar.dashboards.enableNewTablePanelSyntax }}${__value.text}{{ else }}$__cell{{ end }}{{`","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(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true,"legendFormat":"","refId":"A"},{"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true,"legendFormat":"","refId":"B"},{"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,"legendFormat":"","refId":"C"},{"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true,"legendFormat":"","refId":"D"},{"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,"legendFormat":"","refId":"E"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Memory Quota","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":"Memory Quota","titleSize":"h6"}],"schemaVersion":14,"style":"dark","tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":null,"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=\"windows-exporter\"}, 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(windows_pod_container_available{cluster=\"$cluster\"}, namespace)","refresh":2,"regex":"","sort":1,"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":"Kubernetes / Compute Resources / Namespace(Windows)","uid":"490b402361724ab1d4c45666c1fa9b6f","version":0}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml new file mode 100644 index 0000000000..6686e54053 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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: |- + {{`{"__inputs":[],"__requires":[],"annotations":{"list":[]},"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[],"refresh":"","rows":[{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":10,"id":2,"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":12,"stack":true,"steppedLine":false,"targets":[{"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"time_series","legendFormat":"{{container}}","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"CPU Usage","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":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":3,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":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(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true,"legendFormat":"","refId":"A"},{"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true,"legendFormat":"","refId":"B"},{"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,"legendFormat":"","refId":"C"},{"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true,"legendFormat":"","refId":"D"},{"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,"legendFormat":"","refId":"E"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"CPU Quota","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":"CPU Quota","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":10,"id":4,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":0,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":12,"stack":true,"steppedLine":false,"targets":[{"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"time_series","legendFormat":"{{container}}","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Memory Usage","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"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 Usage","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"id":5,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":12,"stack":false,"steppedLine":false,"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":"decbytes"},{"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":"decbytes"},{"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":"decbytes"},{"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":"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(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true,"legendFormat":"","refId":"A"},{"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true,"legendFormat":"","refId":"B"},{"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,"legendFormat":"","refId":"C"},{"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true,"legendFormat":"","refId":"D"},{"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,"legendFormat":"","refId":"E"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Memory Quota","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":"Memory Quota","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"fillGradient":0,"id":6,"legend":{"alignAsTable":true,"avg":true,"current":true,"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":12,"stack":false,"steppedLine":false,"targets":[{"expr":"sort_desc(sum by (container) (rate(windows_container_network_received_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[1m])))","format":"time_series","intervalFactor":2,"legendFormat":"Received : {{ container }}","refId":"A"},{"expr":"sort_desc(sum by (container) (rate(windows_container_network_transmitted_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[1m])))","format":"time_series","intervalFactor":2,"legendFormat":"Transmitted : {{ container }}","refId":"B"}],"thresholds":[],"timeFrom":null,"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":[{"format":"bytes","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"bytes","label":null,"logBase":1,"max":null,"min":0,"show":true}]}],"repeat":null,"repeatIteration":null,"repeatRowId":null,"showTitle":true,"title":"Network I/O","titleSize":"h6"}],"schemaVersion":14,"style":"dark","tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"text":"default","value":"default"},"hide":0,"label":null,"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=\"windows-exporter\"}, 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(windows_pod_container_available{cluster=\"$cluster\"}, namespace)","refresh":2,"regex":"","sort":1,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":null,"current":{},"datasource":"$datasource","hide":0,"includeAll":false,"label":"Pod","multi":false,"name":"pod","options":[],"query":"label_values(windows_pod_container_available{cluster=\"$cluster\",namespace=\"$namespace\"}, pod)","refresh":2,"regex":"","sort":1,"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":"Kubernetes / Compute Resources / Pod(Windows)","uid":"40597a704a610e936dc6ed374a7ce023","version":0}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml new file mode 100644 index 0000000000..e2a63ae208 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml new file mode 100644 index 0000000000..95d758ea2d --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml new file mode 100644 index 0000000000..d9ce9d738c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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: |- + {{`{"__inputs":[],"__requires":[],"annotations":{"list":[]},"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[],"refresh":"","rows":[{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":10,"id":2,"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":12,"stack":true,"steppedLine":false,"targets":[{"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\"}))","format":"time_series","legendFormat":"{{instance}}","legendLink":"/d/96e7484b0bb53b74fbc2bcb7723cd40b/k8s-windows-node-rsrc-use"}],"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":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","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"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":"node:windows_node_memory_utilisation:ratio{cluster=\"$cluster\"}","format":"time_series","legendFormat":"{{instance}}","legendLink":"/d/96e7484b0bb53b74fbc2bcb7723cd40b/k8s-windows-node-rsrc-use"}],"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":1,"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":4,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":0,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":6,"stack":true,"steppedLine":false,"targets":[{"expr":"node:windows_node_memory_swap_io_pages:irate{cluster=\"$cluster\"}","format":"time_series","legendFormat":"{{instance}}","legendLink":"/d/96e7484b0bb53b74fbc2bcb7723cd40b/k8s-windows-node-rsrc-use"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Memory Saturation (Swap I/O Pages)","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":"Memory","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"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":12,"stack":true,"steppedLine":false,"targets":[{"expr":"node:windows_node_disk_utilisation:avg_irate{cluster=\"$cluster\"} / scalar(node:windows_node:sum{cluster=\"$cluster\"})","format":"time_series","legendFormat":"{{instance}}","legendLink":"/d/96e7484b0bb53b74fbc2bcb7723cd40b/k8s-windows-node-rsrc-use"}],"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":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":"Disk","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"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":6,"stack":true,"steppedLine":false,"targets":[{"expr":"node:windows_node_net_utilisation:sum_irate{cluster=\"$cluster\"}","format":"time_series","legendFormat":"{{instance}}","legendLink":"/d/96e7484b0bb53b74fbc2bcb7723cd40b/k8s-windows-node-rsrc-use"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Net Utilisation (Transmitted)","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"Bps","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]},{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":10,"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":"node:windows_node_net_saturation:sum_irate{cluster=\"$cluster\"}","format":"time_series","legendFormat":"{{instance}}","legendLink":"/d/96e7484b0bb53b74fbc2bcb7723cd40b/k8s-windows-node-rsrc-use"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Net Saturation (Dropped)","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"Bps","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]}],"repeat":null,"repeatIteration":null,"repeatRowId":null,"showTitle":true,"title":"Network","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"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":12,"stack":true,"steppedLine":false,"targets":[{"expr":"sum by (instance)(node:windows_node_filesystem_usage:{cluster=\"$cluster\"})\n","format":"time_series","legendFormat":"{{instance}}","legendLink":"/d/96e7484b0bb53b74fbc2bcb7723cd40b/k8s-windows-node-rsrc-use"}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Disk Capacity","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":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":"Storage","titleSize":"h6"}],"schemaVersion":14,"style":"dark","tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"text":"default","value":"default"},"hide":0,"label":null,"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=\"windows-exporter\"}, cluster)","refresh":2,"regex":"","sort":1,"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":"Kubernetes / USE Method / Cluster(Windows)","uid":"53a43377ec9aaf2ff64dfc7a1f539334","version":0}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml new file mode 100644 index 0000000000..a7608496a3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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: |- + {{`{"__inputs":[],"__requires":[],"annotations":{"list":[]},"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[],"refresh":"","rows":[{"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":"node:windows_node_cpu_utilisation:avg1m{cluster=\"$cluster\", instance=\"$instance\"}","format":"time_series","legendFormat":"Utilisation","legendLink":null}],"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":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]},{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"id":3,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":6,"stack":false,"steppedLine":false,"targets":[{"expr":"sum by (core) (irate(windows_cpu_time_total{cluster=\"$cluster\", job=\"windows-exporter\", mode!=\"idle\", instance=\"$instance\"}[$__rate_interval]))","format":"time_series","legendFormat":"{{core}}","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"CPU Usage Per Core","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"percentunit","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]}],"repeat":null,"repeatIteration":null,"repeatRowId":null,"showTitle":true,"title":"CPU","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":"node:windows_node_memory_utilisation:{cluster=\"$cluster\", instance=\"$instance\"}","format":"time_series","legendFormat":"Memory","legendLink":null}],"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":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,"fillGradient":0,"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":[],"nullPointMode":"null","percentage":false,"pointradius":5,"points":false,"renderer":"flot","repeat":null,"seriesOverrides":[],"spaceLength":10,"span":4,"stack":false,"steppedLine":false,"targets":[{"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","format":"time_series","intervalFactor":2,"legendFormat":"memory used","refId":"A"},{"expr":"max(node:windows_node_memory_totalCached_bytes:sum{cluster=\"$cluster\", instance=\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"memory cached","refId":"B"},{"expr":"max(windows_memory_available_bytes{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"memory free","refId":"C"}],"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":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,"id":6,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":4,"stack":false,"steppedLine":false,"targets":[{"expr":"node:windows_node_memory_swap_io_pages:irate{cluster=\"$cluster\", instance=\"$instance\"}","format":"time_series","legendFormat":"Swap IO","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Memory Saturation (Swap I/O) Pages","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":"Memory","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"id":7,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":6,"stack":false,"steppedLine":false,"targets":[{"expr":"node:windows_node_disk_utilisation:avg_irate{cluster=\"$cluster\", instance=\"$instance\"}","format":"time_series","legendFormat":"Utilisation","legendLink":null}],"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":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,"fillGradient":0,"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":[{"alias":"read","yaxis":1},{"alias":"io time","yaxis":2}],"spaceLength":10,"span":6,"stack":false,"steppedLine":false,"targets":[{"expr":"max(rate(windows_logical_disk_read_bytes_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]))","format":"time_series","intervalFactor":2,"legendFormat":"read","refId":"A"},{"expr":"max(rate(windows_logical_disk_write_bytes_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]))","format":"time_series","intervalFactor":2,"legendFormat":"written","refId":"B"},{"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]))","format":"time_series","intervalFactor":2,"legendFormat":"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":"bytes","label":null,"logBase":1,"max":null,"min":null,"show":true},{"format":"ms","label":null,"logBase":1,"max":null,"min":null,"show":true}]}],"repeat":null,"repeatIteration":null,"repeatRowId":null,"showTitle":true,"title":"Disk","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"id":9,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":6,"stack":false,"steppedLine":false,"targets":[{"expr":"node:windows_node_net_utilisation:sum_irate{cluster=\"$cluster\", instance=\"$instance\"}","format":"time_series","legendFormat":"Utilisation","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Net Utilisation (Transmitted)","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"Bps","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]},{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"id":10,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":6,"stack":false,"steppedLine":false,"targets":[{"expr":"node:windows_node_net_saturation:sum_irate{cluster=\"$cluster\", instance=\"$instance\"}","format":"time_series","legendFormat":"Saturation","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Net Saturation (Dropped)","tooltip":{"shared":true,"sort":2,"value_type":"individual"},"type":"graph","xaxis":{"buckets":null,"mode":"time","name":null,"show":true,"values":[]},"yaxes":[{"format":"Bps","label":null,"logBase":1,"max":null,"min":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]}],"repeat":null,"repeatIteration":null,"repeatRowId":null,"showTitle":true,"title":"Net","titleSize":"h6"},{"collapse":false,"height":"250px","panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":"$datasource","fill":1,"id":11,"legend":{"avg":false,"current":false,"max":false,"min":false,"show":true,"total":false,"values":false},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null as zero","percentage":false,"pointradius":5,"points":false,"renderer":"flot","seriesOverrides":[],"spaceLength":10,"span":12,"stack":false,"steppedLine":false,"targets":[{"expr":"node:windows_node_filesystem_usage:{cluster=\"$cluster\", instance=\"$instance\"}\n","format":"time_series","legendFormat":"{{volume}}","legendLink":null}],"thresholds":[],"timeFrom":null,"timeShift":null,"title":"Disk 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":0,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":false}]}],"repeat":null,"repeatIteration":null,"repeatRowId":null,"showTitle":true,"title":"Disk","titleSize":"h6"}],"schemaVersion":14,"style":"dark","tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"text":"default","value":"default"},"hide":0,"label":null,"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=\"windows-exporter\"}, cluster)","refresh":2,"regex":"","sort":1,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":null,"current":{},"datasource":"$datasource","hide":0,"includeAll":false,"label":"Instance","multi":false,"name":"instance","options":[],"query":"label_values(windows_system_system_up_time{cluster=\"$cluster\"}, instance)","refresh":2,"regex":"","sort":1,"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":"Kubernetes / USE Method / Node(Windows)","uid":"96e7484b0bb53b74fbc2bcb7723cd40b","version":0}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/kubelet.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/kubelet.yaml new file mode 100644 index 0000000000..74a5303f8f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/kubelet.yaml @@ -0,0 +1,2256 @@ +{{- /* +Generated from 'kubelet' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-pod.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-pod.yaml new file mode 100644 index 0000000000..f5c72844fb --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-workload.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-workload.yaml new file mode 100644 index 0000000000..801b09c265 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml new file mode 100644 index 0000000000..9869a3d3e0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/node-rsrc-use.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/node-rsrc-use.yaml new file mode 100644 index 0000000000..75e69afa22 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/nodes-darwin.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/nodes-darwin.yaml new file mode 100644 index 0000000000..fe11875324 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/nodes.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/nodes.yaml new file mode 100644 index 0000000000..0da40a7b99 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/nodes.yaml @@ -0,0 +1,1066 @@ +{{- /* +Generated from 'nodes' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml new file mode 100644 index 0000000000..4d1e33208b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml @@ -0,0 +1,587 @@ +{{- /* +Generated from 'persistentvolumesusage' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/pod-total.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/pod-total.yaml new file mode 100644 index 0000000000..9a7e7d0603 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml new file mode 100644 index 0000000000..5c11900e69 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/prometheus.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/prometheus.yaml new file mode 100644 index 0000000000..27f7c44e2c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/prometheus.yaml @@ -0,0 +1,1235 @@ +{{- /* +Generated from 'prometheus' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/proxy.yaml new file mode 100644 index 0000000000..410812451e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/proxy.yaml @@ -0,0 +1,1276 @@ +{{- /* +Generated from 'proxy' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/scheduler.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/scheduler.yaml new file mode 100644 index 0000000000..ee0cf08b2f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/scheduler.yaml @@ -0,0 +1,1118 @@ +{{- /* +Generated from 'scheduler' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/workload-total.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/dashboards-1.14/workload-total.yaml new file mode 100644 index 0000000000..5aafccdebe --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/a8ba97a150c75be42010c75d10b720c55e182f1a/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/104.1.1+up57.0.3/templates/grafana/namespaces.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/grafana/namespaces.yaml new file mode 100644 index 0000000000..39ed210ed4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/_prometheus-operator.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/_prometheus-operator.tpl new file mode 100644 index 0000000000..6ae9dc72e6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl new file mode 100644 index 0000000000..f419caf54b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml new file mode 100644 index 0000000000..054eac4a77 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml new file mode 100644 index 0000000000..52dd78f624 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml @@ -0,0 +1,15 @@ +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.podDisruptionBudget -}} +apiVersion: policy/v1{{ ternary "" "beta1" ($.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget") }} +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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/service.yaml new file mode 100644 index 0000000000..b06c129123 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/service.yaml @@ -0,0 +1,58 @@ +{{- 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.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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml new file mode 100644 index 0000000000..55511da36b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml new file mode 100644 index 0000000000..f7543b0f1a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml new file mode 100644 index 0000000000..4e3b0d9225 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml new file mode 100644 index 0000000000..b81257c168 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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") (or .Values.global.cattle.psp.enabled .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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml new file mode 100644 index 0000000000..4cf1335b22 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml new file mode 100644 index 0000000000..baed83db48 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml new file mode 100644 index 0000000000..5639cc9e80 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml new file mode 100644 index 0000000000..864deb52a0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml new file mode 100644 index 0000000000..076c467004 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml new file mode 100644 index 0000000000..0113b6a5d8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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 (or .Values.global.cattle.psp.enabled (and .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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml new file mode 100644 index 0000000000..f15abf4395 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml new file mode 100644 index 0000000000..30bde920b6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml new file mode 100644 index 0000000000..02594547d1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- 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: 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 }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml new file mode 100644 index 0000000000..da01f3b57e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml @@ -0,0 +1,77 @@ +{{- 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 }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml new file mode 100644 index 0000000000..4827871cca --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml @@ -0,0 +1,77 @@ +{{- 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 }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/certmanager.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/certmanager.yaml new file mode 100644 index 0000000000..cb27e49f48 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000000..07e2e99967 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/clusterrole.yaml new file mode 100644 index 0000000000..fd11b69eed --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/clusterrolebinding.yaml new file mode 100644 index 0000000000..ad9e3ef6c5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/deployment.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/deployment.yaml new file mode 100644 index 0000000000..8a01b2912a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/deployment.yaml @@ -0,0 +1,204 @@ +{{- $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 }} + {{- 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/104.1.1+up57.0.3/templates/prometheus-operator/networkpolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/networkpolicy.yaml new file mode 100644 index 0000000000..cfd5b0b8c7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/psp-clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp-clusterrole.yaml new file mode 100644 index 0000000000..61bc3d9040 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp-clusterrole.yaml @@ -0,0 +1,21 @@ +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +{{- if and .Values.prometheusOperator.enabled (or .Values.global.cattle.psp.enabled (and .Values.global.rbac.create .Values.global.rbac.pspEnabled)) }} +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/104.1.1+up57.0.3/templates/prometheus-operator/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..40e0fc5c15 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp-clusterrolebinding.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.prometheusOperator.enabled (or .Values.global.cattle.psp.enabled (and .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/104.1.1+up57.0.3/templates/prometheus-operator/psp.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp.yaml new file mode 100644 index 0000000000..28a9075d3e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/psp.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.prometheusOperator.enabled (or .Values.global.cattle.psp.enabled (and .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/104.1.1+up57.0.3/templates/prometheus-operator/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/service.yaml new file mode 100644 index 0000000000..d45ab22d08 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/service.yaml @@ -0,0 +1,57 @@ +{{- 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.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/104.1.1+up57.0.3/templates/prometheus-operator/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/serviceaccount.yaml new file mode 100644 index 0000000000..4f84974f9b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/servicemonitor.yaml new file mode 100644 index 0000000000..cbe79e1253 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus-operator/verticalpodautoscaler.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus-operator/verticalpodautoscaler.yaml new file mode 100644 index 0000000000..f225d16dde --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/_rules.tpl b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/_rules.tpl new file mode 100644 index 0000000000..4a8213d089 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/additionalAlertRelabelConfigs.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/additionalAlertRelabelConfigs.yaml new file mode 100644 index 0000000000..bff930981a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/additionalAlertmanagerConfigs.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/additionalAlertmanagerConfigs.yaml new file mode 100644 index 0000000000..2fe8fdb816 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/additionalPrometheusRules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/additionalPrometheusRules.yaml new file mode 100644 index 0000000000..cb4aabaa7b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/additionalScrapeConfigs.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/additionalScrapeConfigs.yaml new file mode 100644 index 0000000000..ebdf766fde --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000000..74d61d7c13 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/clusterrole.yaml new file mode 100644 index 0000000000..3585b5db11 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/clusterrole.yaml @@ -0,0 +1,30 @@ +{{- 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"] +{{- if .Values.prometheus.additionalRulesForClusterRole }} +{{ toYaml .Values.prometheus.additionalRulesForClusterRole | indent 0 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/clusterrolebinding.yaml new file mode 100644 index 0000000000..9fc4f65da4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/csi-secret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/csi-secret.yaml new file mode 100644 index 0000000000..e05382f633 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/extrasecret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/extrasecret.yaml new file mode 100644 index 0000000000..17f3478a46 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/ingress.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/ingress.yaml new file mode 100644 index 0000000000..d2f6af5dd1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/ingressThanosSidecar.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/ingressThanosSidecar.yaml new file mode 100644 index 0000000000..3f507cfa9f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/ingressperreplica.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/ingressperreplica.yaml new file mode 100644 index 0000000000..1d76d135c8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/networkpolicy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/networkpolicy.yaml new file mode 100644 index 0000000000..1296a79063 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/nginx-config.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/nginx-config.yaml new file mode 100644 index 0000000000..e4d91f9a9e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/podDisruptionBudget.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/podDisruptionBudget.yaml new file mode 100644 index 0000000000..48f3f1f5a6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/podmonitors.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/podmonitors.yaml new file mode 100644 index 0000000000..4e748c23b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/prometheus.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/prometheus.yaml new file mode 100644 index 0000000000..5c3c8d4d1f --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/prometheus.yaml @@ -0,0 +1,472 @@ +{{- 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: +{{- 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 | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enableFeatures }} + enableFeatures: +{{- range $enableFeatures := .Values.prometheus.prometheusSpec.enableFeatures }} + - {{ tpl $enableFeatures $ }} +{{- end }} +{{- 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 }} +{{- 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/104.1.1+up57.0.3/templates/prometheus/psp-clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp-clusterrole.yaml new file mode 100644 index 0000000000..71476cd18b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp-clusterrole.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.prometheus.enabled (or .Values.global.cattle.psp.enabled (and .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 }} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..a393928c78 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.prometheus.enabled (or .Values.global.cattle.psp.enabled (and .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/104.1.1+up57.0.3/templates/prometheus/psp.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp.yaml new file mode 100644 index 0000000000..62d3854151 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/psp.yaml @@ -0,0 +1,58 @@ +{{- if and .Values.prometheus.enabled (or .Values.global.cattle.psp.enabled (and .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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/alertmanager.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/alertmanager.rules.yaml new file mode 100644 index 0000000000..b66f052ade --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/alertmanager.rules.yaml @@ -0,0 +1,305 @@ +{{- /* +Generated from 'alertmanager.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/alertmanager-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/config-reloaders.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/config-reloaders.yaml new file mode 100644 index 0000000000..8416d6df40 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/config-reloaders.yaml @@ -0,0 +1,57 @@ +{{- /* +Generated from 'config-reloaders' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/prometheusOperator-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/etcd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/etcd.yaml new file mode 100644 index 0000000000..a1d7a508f8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/general.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/general.rules.yaml new file mode 100644 index 0000000000..8aca0b85f5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/general.rules.yaml @@ -0,0 +1,125 @@ +{{- /* +Generated from 'general.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/kubePrometheus-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml new file mode 100644 index 0000000000..9de5f5bc9c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml new file mode 100644 index 0000000000..323f41f9cb --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml new file mode 100644 index 0000000000..312d73c889 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml new file mode 100644 index 0000000000..136595e801 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml new file mode 100644 index 0000000000..d308b7473a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml new file mode 100644 index 0000000000..2d896e59e4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml @@ -0,0 +1,168 @@ +{{- /* +Generated from 'k8s.rules.container-resource' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml new file mode 100644 index 0000000000..4915b25e73 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml @@ -0,0 +1,107 @@ +{{- /* +Generated from 'k8s.rules.pod-owner' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.yaml new file mode 100644 index 0000000000..c61bd222ab --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml new file mode 100644 index 0000000000..6194e9c614 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml @@ -0,0 +1,273 @@ +{{- /* +Generated from 'kube-apiserver-availability.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml new file mode 100644 index 0000000000..e6666a6f41 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml @@ -0,0 +1,440 @@ +{{- /* +Generated from 'kube-apiserver-burnrate.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml new file mode 100644 index 0000000000..d145341952 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml @@ -0,0 +1,53 @@ +{{- /* +Generated from 'kube-apiserver-histogram.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml new file mode 100644 index 0000000000..30ef9a4293 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml @@ -0,0 +1,159 @@ +{{- /* +Generated from 'kube-apiserver-slos' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml new file mode 100644 index 0000000000..fcf35f389b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml @@ -0,0 +1,49 @@ +{{- /* +Generated from 'kube-prometheus-general.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/kubePrometheus-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml new file mode 100644 index 0000000000..7a0d202324 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/kubePrometheus-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.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 (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 (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 (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(instance) GROUP_LEFT() count(sum(node_cpu_seconds_total) BY (instance, cpu)) BY (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 (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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml new file mode 100644 index 0000000000..c9d61ce37b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml @@ -0,0 +1,135 @@ +{{- /* +Generated from 'kube-scheduler.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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="{{ 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_binding_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.9, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="{{ include "exporter.kubeScheduler.jobName" . }}"}[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="{{ include "exporter.kubeScheduler.jobName" . }}"}[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="{{ include "exporter.kubeScheduler.jobName" . }}"}[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="{{ include "exporter.kubeScheduler.jobName" . }}"}[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="{{ include "exporter.kubeScheduler.jobName" . }}"}[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="{{ include "exporter.kubeScheduler.jobName" . }}"}[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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-state-metrics.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-state-metrics.yaml new file mode 100644 index 0000000000..d1ad3cae5e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kube-state-metrics.yaml @@ -0,0 +1,152 @@ +{{- /* +Generated from 'kube-state-metrics' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/kubeStateMetrics-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubelet.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubelet.rules.yaml new file mode 100644 index 0000000000..39fdddf3fe --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubelet.rules.yaml @@ -0,0 +1,65 @@ +{{- /* +Generated from 'kubelet.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-apps.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-apps.yaml new file mode 100644 index 0000000000..2a861a522c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-apps.yaml @@ -0,0 +1,568 @@ +{{- /* +Generated from 'kubernetes-apps' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-resources.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-resources.yaml new file mode 100644 index 0000000000..1d32f9bbad --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-resources.yaml @@ -0,0 +1,282 @@ +{{- /* +Generated from 'kubernetes-resources' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-storage.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-storage.yaml new file mode 100644 index 0000000000..b988445653 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-storage.yaml @@ -0,0 +1,216 @@ +{{- /* +Generated from 'kubernetes-storage' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml new file mode 100644 index 0000000000..af34a23f88 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml @@ -0,0 +1,193 @@ +{{- /* +Generated from 'kubernetes-system-apiserver' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml new file mode 100644 index 0000000000..205bd59800 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml @@ -0,0 +1,55 @@ +{{- /* +Generated from 'kubernetes-system-controller-manager' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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 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 }} + diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml new file mode 100644 index 0000000000..66b1d62001 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml @@ -0,0 +1,56 @@ +{{- /* +Generated from 'kubernetes-system-kube-proxy' 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.kubeProxy }} +{{- if (include "exporter.kubeProxy.enabled" .)}} +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 or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupAnnotations.kubeProxy }} + {{- with .Values.defaultRules.additionalRuleAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupAnnotations.kubeProxy }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- 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" "labelsSeverity" "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 }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml new file mode 100644 index 0000000000..2a55676735 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml @@ -0,0 +1,379 @@ +{{- /* +Generated from 'kubernetes-system-kubelet' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml new file mode 100644 index 0000000000..9890b1c959 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml @@ -0,0 +1,54 @@ +{{- /* +Generated from 'kubernetes-system-scheduler' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system.yaml new file mode 100644 index 0000000000..621326d0ad --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system.yaml @@ -0,0 +1,87 @@ +{{- /* +Generated from 'kubernetes-system' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-exporter.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-exporter.rules.yaml new file mode 100644 index 0000000000..5d4711ae08 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-exporter.rules.yaml @@ -0,0 +1,188 @@ +{{- /* +Generated from 'node-exporter.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/nodeExporter-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-exporter.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-exporter.yaml new file mode 100644 index 0000000000..14738cedfa --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-exporter.yaml @@ -0,0 +1,801 @@ +{{- /* +Generated from 'node-exporter' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/nodeExporter-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-network.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-network.yaml new file mode 100644 index 0000000000..8dc60ef66b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node-network.yaml @@ -0,0 +1,55 @@ +{{- /* +Generated from 'node-network' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/kubePrometheus-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node.rules.yaml new file mode 100644 index 0000000000..e2911b905e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/node.rules.yaml @@ -0,0 +1,109 @@ +{{- /* +Generated from 'node.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/prometheus-operator.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/prometheus-operator.yaml new file mode 100644 index 0000000000..1f288dffe3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/prometheus-operator.yaml @@ -0,0 +1,253 @@ +{{- /* +Generated from 'prometheus-operator' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/prometheusOperator-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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/prometheus.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/prometheus.yaml new file mode 100644 index 0000000000..9dfeb1f9db --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/prometheus.yaml @@ -0,0 +1,707 @@ +{{- /* +Generated from 'prometheus' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/a8ba97a150c75be42010c75d10b720c55e182f1a/manifests/prometheus-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.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.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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/windows.node.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/windows.node.rules.yaml new file mode 100644 index 0000000000..7c25553861 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/rules-1.14/windows.pod.rules.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/rules-1.14/windows.pod.rules.yaml new file mode 100644 index 0000000000..86340b5c05 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/secret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/secret.yaml new file mode 100644 index 0000000000..e4a1e73c7b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/service.yaml new file mode 100644 index 0000000000..d61b9d6ef3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/service.yaml @@ -0,0 +1,80 @@ +{{- $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.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/104.1.1+up57.0.3/templates/prometheus/serviceThanosSidecar.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceThanosSidecar.yaml new file mode 100644 index 0000000000..15b89c8c23 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceThanosSidecar.yaml @@ -0,0 +1,39 @@ +{{- 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 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/104.1.1+up57.0.3/templates/prometheus/serviceThanosSidecarExternal.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceThanosSidecarExternal.yaml new file mode 100644 index 0000000000..453eed7f1b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceaccount.yaml new file mode 100644 index 0000000000..e97b989bbd --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/servicemonitor.yaml new file mode 100644 index 0000000000..a36f3e33ca --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/servicemonitorThanosSidecar.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/servicemonitorThanosSidecar.yaml new file mode 100644 index 0000000000..0f70aabb58 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/servicemonitors.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/servicemonitors.yaml new file mode 100644 index 0000000000..a7a301babc --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/prometheus/serviceperreplica.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceperreplica.yaml new file mode 100644 index 0000000000..4bc7f7b869 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/prometheus/serviceperreplica.yaml @@ -0,0 +1,54 @@ +{{- 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.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/104.1.1+up57.0.3/templates/rancher-monitoring/clusterrole.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/clusterrole.yaml new file mode 100644 index 0000000000..56ca9f5eae --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/config-role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/config-role.yaml new file mode 100644 index 0000000000..f48ffc827e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboard-role.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboard-role.yaml new file mode 100644 index 0000000000..d2f81976a2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml new file mode 100644 index 0000000000..7b51a0bf7a --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml new file mode 100644 index 0000000000..d73b257451 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml new file mode 100644 index 0000000000..8865efa932 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml new file mode 100644 index 0000000000..9b05cea2e8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml new file mode 100644 index 0000000000..2afae10ef7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml new file mode 100644 index 0000000000..172c36e9d1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml new file mode 100644 index 0000000000..19836ec4e4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml new file mode 100644 index 0000000000..940f18869b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml new file mode 100644 index 0000000000..d146dacdd0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml new file mode 100644 index 0000000000..90d24c2061 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml new file mode 100644 index 0000000000..53a9ad6897 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml new file mode 100644 index 0000000000..b0f92e63b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml new file mode 100644 index 0000000000..1fba8f23f7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/hardened.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/hardened.yaml new file mode 100644 index 0000000000..f9a66151ee --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/hardened.yaml @@ -0,0 +1,147 @@ +{{- $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'] +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ .Chart.Name }}-patch-sa +{{- end }} +--- +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.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ .Chart.Name }}-patch-sa + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }}-patch-sa +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' +{{- range $_, $ns := $namespaces }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-allow-all + namespace: {{ $ns }} +spec: + podSelector: {} + ingress: + - {} + egress: + - {} + policyTypes: + - Ingress + - Egress +{{- end }} +{{- end }} +--- +{{- 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/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/configmap.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/configmap.yaml new file mode 100644 index 0000000000..53cb898214 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/job.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/job.yaml new file mode 100644 index 0000000000..8f2771740c --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/rbac.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/rbac.yaml new file mode 100644 index 0000000000..e929a19925 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/rancher-monitoring/upgrade/rbac.yaml @@ -0,0 +1,131 @@ +{{- 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: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-prometheus-stack.fullname" . }}-upgrade +{{- end }} +--- +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" +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +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" +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 }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/extrasecret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/extrasecret.yaml new file mode 100644 index 0000000000..587fca2dca --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/thanos-ruler/ingress.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/ingress.yaml new file mode 100644 index 0000000000..e245ad448e --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/thanos-ruler/podDisruptionBudget.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/podDisruptionBudget.yaml new file mode 100644 index 0000000000..83e54edf9b --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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.name" . }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/ruler.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/ruler.yaml new file mode 100644 index 0000000000..b281221563 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/ruler.yaml @@ -0,0 +1,189 @@ +{{- if .Values.thanosRuler.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ThanosRuler +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 -}} +{{- 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 }} + 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: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.additionalArgs | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.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: +{{ 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.name" . }}]} +{{- 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.name" . }}]} +{{- 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 }} + portName: {{ .Values.thanosRuler.thanosRulerSpec.portName }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/secret.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/secret.yaml new file mode 100644 index 0000000000..acab7fd9ae --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/thanos-ruler/service.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/service.yaml new file mode 100644 index 0000000000..be0c844591 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/service.yaml @@ -0,0 +1,53 @@ +{{- 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.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.name" . }} + type: "{{ .Values.thanosRuler.service.type }}" +{{- end }} diff --git a/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/serviceaccount.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/serviceaccount.yaml new file mode 100644 index 0000000000..b58f1cd4df --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/thanos-ruler/servicemonitor.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/thanos-ruler/servicemonitor.yaml new file mode 100644 index 0000000000..b2b138b498 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..6fcb8b3a69 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/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/104.1.1+up57.0.3/values.yaml b/charts/rancher-monitoring/104.1.1+up57.0.3/values.yaml new file mode 100644 index 0000000000..0bf19a8572 --- /dev/null +++ b/charts/rancher-monitoring/104.1.1+up57.0.3/values.yaml @@ -0,0 +1,5431 @@ +# 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: + psp: + enabled: false + + 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 + + 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 + +## 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 + + ## 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 + ## This configuration is immutable once created and will require the PDB to be deleted to be changed + ## https://github.com/kubernetes/kubernetes/issues/45398 + ## + 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: "" + + ## 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 + + 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 + + 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 + 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 + + 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 + + ## 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 + # 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 + # 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 + # 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 + # 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 + # 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 + # 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 + 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 + +## 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 + # Users who are deploying this chart in GKE private clusters will need to add firewall rules to expose this port for admissions webhooks + internalPort: 8443 + + ## 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: {} + + 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: "" + + ## 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.72.0 + 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: v20221220-controller-v1.5.1-58-g787ea74b6 + sha: "" + pullPolicy: IfNotPresent + resources: {} + ## Provide a priority class name to the webhook patching job + ## + priorityClassName: "" + 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 + + # 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: "" + + ## 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 + ## 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: 500Mi + 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.72.0 + 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.72.0 + 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.34.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 + + ## 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: "" + + ## 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 + + ## Configure pod disruption budgets for Prometheus + ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget + ## This configuration is immutable once created and will require the PDB to be deleted to be changed + ## https://github.com/kubernetes/kubernetes/issues/45398 + ## + 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: + ## If true, pass --storage.tsdb.max-block-duration=2h to prometheus. This is already done if using Thanos + ## + 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: "30s" + + ## 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.50.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 600 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

j5Fr}7`ZlAIDVo5hmjyI` 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 l67`%H=1I2((d$-{h-1qi$JeW2gm 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 z z&MxQFC0#S(O_S8do-Gj-O=SOyfY2;FfY-puzd};p;>G{oT&SSNx;zp2 zfOJ#xWA+1V>{qIFy`I4ux5ASp9|LvSRV}1CrSp{fh9hC%h)1mmaD*uMPxS^W;ad8Q zLp?#k?iOHd8eA(49Lei9{+YT1X9yhWgvECiT&O{o=sqYQy40PkCHfJ*(fRO4?29bD0kKW*XiqGj5x<09WsC%0zwl6eZcni}iEVpL>ILxM5qQ zT;f#&3v0eyh*{HVs-9sbQ^(6GHbHS?s~=TX+l6R?_ohbv(e}8Gus@a>F1cH_`3l{K zccGt5pT=O-G(0Z3ke(xV#2hcL;_J&Rx}T|&GNHMCsYws)47*35mS0A9h+kcFN%(_j zcV&^Q4pJ$XMRG&4!SF$~?6p_W*{aW9N8#$=u73+qXw`^lZ=L@zY18MB%^u4=FmGde z$H;l&aom>n}bkV;|>*_pSm5IT0@Ge@u*Fk&%vQb`T?fMr5lFLbLJ^wpgV)F zGOFZ~=m@CK8(KZF&VQJZSnoW{y$Fza+?BBR0U(NK0HOK{V20ofB9uNBqjHRdyzPLZ zqtuDtT5<)gQ!64pzA!Y~$Tpgw8(LKrU=VB1F%&&Vxcod$R$LZ9Vl8oAJ&&2BH9Gq27Z!2@8_2 zTEtjK`WyU&Mi2r}cwLou6iJqu;q9IWyg3Aa4|)o{6aY1$VwXGgW3`ekVX`ZvA=ey6t^yA{ibx0tMeLK3D@l1_fiGhU5{;!^ zs#zQI*dI%vQgbta-c`R8xAoZ(CqV?u1+>*#fm{Yn{<0#06LPlEymbv4q_bTB+F>w7 zMuCjYIRzwG@_K%wiOb2)YGqQLiUWNIu(s~6clt$siilvPgc?6smed~2W%dZuPgaAw zzej3ngg+kE@J05pqbO( zV_%7VoTh`>^t)g}KCcS{=0^hM+OAyDpFK_!wp`1notqn2OP}21gZTWLTF!F&d>fN5 zDL4$8p&aB=kmmMSvJ&bA$z|Qo1otPrbKg?3e;oqx@i~y(&Y8ECLY^p7CwyXKDbG0d z^3h2oqfu<@e=M9BmG&)tFzNYy8b1N7@Ze%$p;tdq`L|Y` zejTl2(@JlIgQdL=A2_i0aO$Hh^y2qMLreHsoV$+NZI+POB|*okAxe-4KN6zFx+ysE zCwKjKz2{Gw(XpX0G${+tYVQk^m}~fY8f*h={qrAvRk9i~8+`||HHJb+{BDY}3unMn zHKaJkl~op27)Jaa!GBA5LPwI1%_pGBa<~KYG$09M4~|J~x2K7uAN5rW62>uL$&xk8 zYKlQx?eR<-25ISm#Am)y8@kQPS}V981^NPP``TRnG>GB?575*Uf;jkB)7vU0N!3XL z4=qNx9I-OV4&y1Y50v*9E72&F?!2^y%|1l>lc)0BH1g12PkC1yd`RYpZc!-}-0al_ z?zc|QY%ELXpzr4vWSL!;nz5p-%??}J)j9cyTC$iVnAbjZ8nG`YSV~U=bIB@hb3ybq zAupFdRP}N4v;7Xne6YpdV!m!&Jau+r)I{jbDD+mjRhM}-m_JdEE+Jk+73`J(1 ztyJVExpIjXydSB{K93CEuD)3Zub4$@xOPUNjlL6i8sFAEOQqCp4Fema3~(o9`-D@j z0NyEp1+2ntm}Skv_W&lJQsui3b9S-QlVkLDb-0>PbluH#{v}80^aaBxu%Z? zTobEiZ?YfeA5z1>IFl@MhDY=aGLF6IG^j*QB9a`K5d7_X5du{|zih;B^fXOh5kD($ z72_J-LSJlq2wexDtHmT=J-Jg`5=vlvy08z4JWf>MPR?XE5{6y z_`HZ_f8qpQfA}8%OH>Mc57PN4!~QH85f_WQ5B@HH6L|YN)o6T44zFW%mJw}WZ?n^` zvHv9E=lk!VPT&ngz0rxl^S9$aFVR*^riLreFih?TEF&uO!I-8tk--`m|CgE`6O zmW>|OSIq`Pet|=$2ivK|Er-`Rw)%^URwG_Y|Mc zLiZ0>bE;{xRGbxZl)M-Gn1UYqAuER7UnhA*Vs_5Z+3};p%-8b8tc&JLT3a>~oFtD2 znPL|Rkpxy&0Y{4Hm|VWm9xdJn{HyI8kOgD1O<5~O+TMXeVaq!9d9i-UyfmkJ@-f<5h)YN zh0YCpw|)WpU++VHP?rsRstsnNW9{*SY{G5x5A2^$2iV2okgGug@GKqIoX%wU6!?HN@)V zI>?W*OHX%OMVliaaGD?wjt0M8cGl&_>d3LWj{`I_XmkK;$;W*O1ec}tS?50)MH8R` ztN9pQ6F4QS<#c)8Rn^VfCn7e!qub!8;$Tps?Gi(noB>S$5Jdp8kYAw^qLNy|((GnN z{AM9b;iKY`@llA8(fg8;(8H3@5>jFM!i!%~A`)Y;C~za@&V7yiaj0~XlD~}bQ_CuM zj3yh0_8`r|_mIEX^9Y>OJ;9gxL3d7z1I47=IOdVA^S+Ek5BuzkhM<=UqYwF7wWM+O zS9LZA*0a;|20F}4@X}tMO?!WjbXyVrK_}`z{dE*@K!bb|qJ)!DdzgFiCVF3fX=?%N+8dd(J6b<84&!M}q_SreOb z?KiT^0Y7G?FkDQrF`rdQ2fP42{k5GtOpTD;GA_dNh5O=IbM3sBh0VMOpNrOFr{B5r zw#kE;DQJY7^!#K~{frD-a4UDMxA<9|374ox#l+4+8^n)7jDsDGVgEfjTmE7> zl(>8}8oM93tCpNU^xg`UR(KSZNer}AnNjhd6nRUZ8>IBR%|R;op(}r}s$VN`+dW5g zHGR4my3b5!O;IC-%93Zn3Vo~bM9K4?@r6Kbje%If@|^n78P>vaK;7llnYR2r$ViU1gVCds%pMut(Xe9T zMQ9d>%MOy|9cy`0X(E&z9U8ye^s!9Vo%y+vs|XJ3_jn{WvTkiO$GHe9Vi{g6AKXnt zThfqr!bSB=d+w?>ZAayoV}d)Q^dVZRAK!UZKZgy|>@%fqS#?}IgT^?IJjHQ{I#A}n zxfi~B1>&~YJC|N6$}6*vlzqIea7Vn>D6`AbMz%ZZB3FVOKi42-hQR3(8yL10!x^Hl z$qdXFJ&212dM&9W;E|o$hw<0l=*xq%t$xuP(l*_T%LFtE%9`S!M4Ah{C zAm-KB0_ifmY?W9MglQs{n(iy#M7u1o?K|40WYKJp+T;j|y|okJf+p^Q+WPWQNkd%$ z&ZkQkR|HOVAu>Dr0cV*Vne2Qh&R<1>?*nC@)z*evjdLZQ4qx7VP_H}tZ{%f zp(KK2`Sm*sgZvMulZy`HpLcEPe=r8|cW!E|&NKx3eclIf!?hq26~m*Em(sX5ZowxZ z&A#pTJx3}3zNc5FcFZ(nG2tw{#JjEV#_#`U2*V1Di@Ttwy<}ksxnXhT>$w$?qDf8J zYxGlrdA2j_6i#%JWyW07x6Y_%z|lj9MU^sZ7}UEG;4$2BHz1!;otUH4gn0+3vU-rJ z9a#U15I`QP7g_H%(6@OldmRs)A9y;J*Z&AICISw}GWtVRjl#N>=q)4B7uEfS#{MW> zRDwpIr4`8@NTos>i2hNOOx|XmBMsm@BuzSmN@}MAzGDKrH$n#R+rLAUZ-H3&%Q1ZE zpOwHM0>Q4|mSZ&`+x$>E#K=Q!$oNo7QX zvpJLY%?Qn9hcGkCr2bqO-SU@~%c|T@WGmfx*YlM>waOI8y;Bm)3S5K)GDUrwiUKzG zc5l1t-(q;zj4JuY9a|T|JFxj-tfI!T; z^Pq3{p45H;5`RI=3jjENmFmAZgCoeRtqQQQrQ_bkk2~C(t}v)ODLZ?Ye$tXQ?w$%E zhmL`#g|}WxDe2KGI2w~yd4xo-;{{>TB4xW_+Az3TC}i%QYs>X&^TJbZ=bU4XonyOa zrNy#Y$P0^HheHAG0kPsn$4?aRUigK;duJ{qvFB$;7_bcvv6&?~_Dhi3N|M2Jz({F? z+t!oVHtbxPk9X*by6-GG=f25YnpZSlx%)>3q51+={Q%dpDFh8VMm@1vcMhW9*K*fK zovB*S)EQuX^61yx3c?-jpEtnEvKFw9U9P=wzFJ5gJS{&;DYt(X53i4Dopd+8PIs6Y z=p2+KR7ue3Mr3@0(a5eIh0_Pwf$7y*Mjx~`SlI0lD8`J$`%_EqK@VAdmL5T4!Hb^L ziWxCsw?L+m+)E>joO>i1vU))UErN)-j5Zw>yuS7iEO>PyF(XXxIx!<-#Qb*Ohg-lZ zCbGY~1R%)5Fe84d=%R|L6L$B(O%|NZ1~ ze<;YOV##2gZYk%z;)Yq}eppiM0@8yCr^U|w$k{g|^>;MB2-3WV(VfMN2Nu=lxGnSN zQVL&~P>+l1-04-*U0>VZhAAJ>sGfVo38(2$_GtUOXu#$8{bzt@X!xXFZ?eg`6`~5K zjofG#N7xg3Wt9iByU&XBlXo{HuM&KY=eyB)CtI&v-1zVY>iIPPfRPO>08Do`G=L2$ z2T5#}m92czfowfRiWbJCy1@?HNMz6Zc-4R|Ef?yBV{TGS?9`H=&Njiweh9}E`49v= zZ&ntto}-o9QB2eWPnQ)sa;Z6uXtP3 z5Fhh~1}(Th%b+ZQY;6NCWKIADcnk}OVf_9{vQ2YMZ|t`?KQ2)tkpR{uE*{1nC?Q~ZmOyG0Vhn`P%=qM#~O`)AUyV&1DcF@4Qu2r`6yav5>AjNx~gCVMSz5X8lnh& zBt;B`^8@xLYPn8~$s}r^HadL)g>y(Vd0au7cvp8^Z7e4HBWp;At^i8nF;!MQA-lNV z38%M{W4>T6Y+iZQ^sPoP&?2NNV$qc z_D6D24IT7^dPoM;&z z>H=8cW&(!DyCKn&uhF}wGeW3sWc9EpvL3(nR`tLy!g4i1J5}~~!HPYOjS&r-F<5Gg zVcs^6S?dB^*4RKx?%x#+`VA35R~DKXD^Y8OjbTBG%njdLljMjks1{7d=GSqpW0FA; zrfs5}2NfwH5-?O`Bx0gm4``saO3+Hl1+YwZg|BkOf*#@mU3;N+IKxD2M1cOx4uH#^ zE5OCHpSkXnLkiBJxC!XrVu)D|@pc-8BFq~CeUQF^1x3WfG!G&&b|7eIgd81T41d>s zXheFWW{8>U*&_{oup2yafmb(X%$h0i-xV}wjUsH4k^Ci@jyx>$dS_>d8AC`Zm5U8j zn--l^ef}4$0mP;%|XPxjr&AVkgaBG`0EG|kh$U`_Ri+l9F}N=S}IifccXw-XmFQcgddGmFBD0| zkW4y>A5&KZ+Eo4Ejd&bI2(bfBm2=+vSY~&-rwp|e{HCSPsD;4;Fb48YLy}gmTX7`nPIU` z=?`GeEZc*`!;?D@SluNafA4;Ni1#Pzc|Yp%?0W_Am3{Azm)rg|??2N)R-_>8GM;$5 z&mUw-I%6qh7$^8ryZ!!KS9!`ItMBde1ODenLY}ebhxZr5a|)pXH2p_1)A%gaN2y(V z345}xAgl@k=35>69rtTSm%lu(y9@AsZlNDuE3nExm7gR&;~@>Zy3EKyf5Qj zpU30aR4Ild#9Byx*^Fu9<7;j3#kk&fSWu55?xz{&u*S$iJ6C4tfmpj`&z`J(JY_Lv zER>)Mu|BnG_p{8b1k|`t$~*e6v@=qaD>O1e7E|ee862vM7`gTm&<+=!oMHpq4yF^# z397RzBGnqFw8wh1oJnI{#lyi&zw8zKaA<{dwRbWOSI5Q!Qvqx9`YX-3#JNR=Xufz{ z`bKc-5G)xvT_%c9T|8-mOiwQW$l9NX5rbP&*jGmf%Q`#CG9$$@?P+r4af10sU^Sa_ zN}>4cb)%D@fMB=5Jt2$KRER^jVgm%?h@?+Zh19S23I+5sZIm5^$~bNngiz48VWjz5 z@yEYfTkinzS(`9xGT@7_guv&bBF6t=yiT_Mntqih|^I9S`8Or?d=p$&>MFY zVTC_EMdly)AVYC;H6C_;jOUb!MJ71~yVG{r7Q6QPZ%5H&M?kSKb$+&j-FG@47wxx% z1J(2*<=ppa?MFZfDh_{6?1TKR5-hrNXc~YK%L*CZsCLJqfEhyxl7?#b7n|1&%K8R| z$!VlYswESVdapIr@nJ_il5QL93SE$U)bSJK_UGHvd_j;JTHO!6Lr3qrnrcw`3x$?_ zW3WzR)jVbnAM?*F`*j}fpVD6T%yj~YrAGtPZiU^P!!sHs%uz#fW0HGdm5U%QM+opX z+R0G4I8zixaq6y5!a%LuNE6Fq(on`+B?jxSb94RatHJHBG*zNCmOF#F>OWqh%qq9b zJfR>j(Kn4r1qOd%ZuUc;2%f`@3!)k{QmeUNi0%lq3%g@pL_>)rafpZ!WWoGD=~@pX z$RMD0$55r9(Lnb{I9Mad#0YR}0C6#S8VqqUoTvs}VS`3KyJOs#QejYK?_fSXRR;P< zRZsohq#GinVIcF+r=O71lN=0=#F(!OQyM7av{NcP8ZZ)~5{w_pI_BMa@~jbYDr-$= z*~T?{GHpDaWTB+Y2RP zfaet8LP1VFNxPbU3#smM|1ZP0#AeG{@`9U+ah#wcY%%3gor%`8b@mfe4B zO$Sz5d(8BVmw&TdE8#fFtblI}ngkU*u^Iy%oMxoY-#o*X|8>Fr3AD z`Ro;Ri0ys%S$3N+L3ahoRr)`6Z;{7$h2zG^)xDU;r5|rOLvqL~aJX@}X|e$yoY5}OS zu34!9yvh$Mmq7Q62Z!sU`t%ZIic0Z91cmO$wDTaIaP12RM-d#dE%*3^PWti7r>eB; z=l{G{bU%OUorh`5EKIGzCcyH-XF97>7RO444Zc6Xj-+@;lElv$`Sni$X%8_x<>9=4 zPq8y>O~!octnsva1W(<$Q2P&k8P$fSrdD&1e~LAl_$HVKX^mo#755a@@Vc1$%hS&i8IT3LS*v`~;UJ_Pa9=$kevI1FrEZ1!( zFlt{Ry~;3xt+(-fzebN&P!^&>c$Zs=b$Z>TE->=ZZA60X(}HyQU)^;amI8B=Ul{g1 zld00!#z>1@E>xAo7ROCoz@8_v@yB1r2s%nTy6kHW_I>B#q}&@`D&76 zvS1ee$!$6J=y**@%Si{Be^Xn=h3Md*g+o9ga~(i*QC@3xy3^_RpTrg^X`x=dpL`+V z1d*K#yCcNaf7VKbGjJOb&)9NY0LUT71;M1?G_rqS(m3-=T@lEf>i9s*?5Nf#r5wGh z9e1O{N~`(NKo+-6<$!FMIblfhsb6}0gA=s2fbu1eYK!&6HG5(;@FXm^Su+0bq^S@V z22~8*$Xf@1mLC!tSla4lOIm8f2FNQPA2>hT4C#+Jm5H#Ft)V_$a;)HhGLCO~Qbr*G zTY_$w^8_;^?ofq^OT|1;Yx@p=TPYeZsKN_Xp75!}q(*mUvG|#>{BOGPg+HFU!>0Caw0pw?(Lo6JQK2mHw^j=>RDe8SBp z=zmfU3lXvo5Iv1f$GN;N|53a4NGZToMgE;en&lOhKh5N++_5A>5D)oldnx9ER3PSp z(EdI#O)1mxFSP3?cz!t+5XL4}Xjw*xFQ@Tf(26-`0x-48RFW@_~ z8D}Ji8Ln-<&5{uX5({jL4CV6CWP9GIQeoVz%z!w=o1wbZEV4L6%)bF$9CRONWejxR z*{nH;o7G3Bg`0Iv*y{ohIrt=!Y)^>*7X%;$&-J%zY7SNkGS|U+CPeIXH|F{A2eP>; zd|QW+cz0`B5^I!gQj1#>xtm8~m`W`@yOTHVS8^u|&Xegqol@%xR;A^pbtQ$0iF880j0V( zVeMcx9~@TbX*|ksLT65M-A9tYc+%m9Ev#g@{0E9h!Q9DtIa>;s&+Br=OYB`oTV{&~ zY!`oJTTtJD_(l}U-`hwHbN<690X(S=u2waM8=k*sMaAq4X0V^#`Ed;2bo&UFTp^Fu zoQ3g_!x*|LZ+`iDzw8K*{uRJe|D+OH@O!{9*K?*be&gFNq1>o-TtT2G;ur zQ`!W}v1WBW9TJ5OU7_ux_Fj?;uHQXDZzt3q{P2PYlpbgZQGKJ!vg<2`ulH0QygbYo6 z#T>efb)FM87A+t|Q)BUjB=L?iB$AJ2Ce`X63pSLTycSDM{f9X92Uov#I$RP!Ptyg* z0o;n;hwg>Qfo8|p9*}2(TC!3^Air8Oi9Y}D3F~wLj%nf}9iDSvF`s$v`0p+f-)>Ky z3e8<2MHY-WXk1!8sx4~;or5O|#VR@>lnIV}8|Vu%bV<3S#QDN|;o#I=EIx!MpnE#^ z*Sr&)j>vObqC9D*ll%fj$W6{ThUx|UR;zcwY)gcU0z@&1SQ#>^fy_H$KLw&?-%Bb& zNB!QaJncEFnKVkA#TC*Ko4$fWnwC*uSx#nC_X`{5VSX+O8->{f6O%I(3Arw)e zeFSX?0#g+117?%=C7r0yc5@s8Rx|{e)o8+2uTe+vZtR4kR7&2ks!hM+Xrh8sotgf? z9V)6J#iUyC^&-sZs6@VVHbPYBFjx#n1(#tHSedS$Kf;4Or6H=S@+$7#g;BRQhazMb z`_w9Z0P3-95bAg&N!%$G7c$UIuJym-~R{M9i#FpL= z4>AHbSYuSfoW}u*Sjlp!pe^p&?Sd$sMO69WV58GnCaf6+LDl5TuNf?oP>NN|G?$`9GLg{^72QA}2Pa^nH3I(0m@-SIjpqJx!j*B7BC3E8}V1^@MB z=bYeafA&v5kXyeYwRNe*Q5Y(T2tY(g8M@d7ChY9h3ncVPfJ4OYYJ0Ma#N)S3*) zBCKeQnDF2X zeI#Ny4_J*%@={Sj_uUpGW<|W|kE?iyvM2#5$3V7UZPPT}{J3{*CJr{gA%KM}D`Jx@ zM-C5Gv8W=^rIzKoAQNY)k=wr!+(?)JcR$jwfkTP_m-=tSj{x0gsZA6iz}+3Qf^s(d z)ocR_^nurF90bq{7*ZpJ+^qE6uP|S29qMYs)V~-Rpj`sc20?KBtJeq1Ly&zgO4Qql zMOC<2szn7sRWNBG>BqnYJ?l<`8Fpwy^%a)m%>Ak@`4&FzlAy1wqd&{ZH}prZW69m~ zM&%b?=H-;MOS9**zk(r}%LWy?7!_c82~WY3MpxPK>bgKW1zBLCvY(Mn#WG+tUM`F1 zXkUD!D!q1+n$PP<3iuzCea;e0?{}s$t;YZ8k+l{o_b3BNl^j4r0d{!1JCc=@%ikWA z5G%gPJo})js8`zN+D`X`8HG%cD+OIGjMMitYmkn%^I7Z+H5Fqxf-y2p23MM@^fOgQs!x{z8=VdrVlICK%pg+hlXxA9 z0oT?s5(PevQbKDo?r|3JUYcf^gq80rTnrevZpu+M)L$>7`zW`~QBp&%bcbwA~s z%5-Ss;ROmOzQ!=9M~;xhAXB)q7ftr>eljqtKKa;bYrQI|=zi~*;tWaGzKGI~0^Ylt z1i_%Pocd4c-bWP#D&3{2amil{fLFSpXz#1j60+U)@4HRDeino4^Aubt?#Ii6YREg( z6;X}%R<+;R`oo|ylTM`4NBLW<`F&{awwx3ZSnL?D!p#BdVTdjJDlCkh-YM601%h#I zyB3l30wdd# zZ#I1XHD&HU(f0LNa=+4Y7diqNYof)?@vR%E<~dzZ_4DQ8$Upx>ZgIec;*5z&;Li^y z*X4M84;_c4X&M^TM)m{eDc%BH0mwPRKf4Zn<#4T6RT{HJ{th>u0c0zvkD>I<=f@mQ z5)+RGkz1!;bWxl#{I4K#i$f!}IGeMax>;uiL~fnM_*Yliy;bw4`ACy;Nv$d>%qiVd zu)sE?rymTQ-tR>klMgEYET-+w6KNYeo~JQWSB$LwI^93M_w_3?pKDxMRu~ilo4L17 z0JAM=Cr}s>#sc=m)TR?|#%l(R_cGmsRUK;ce!@6EW?KAtJ7>Oc4v7u5##_YX7f=C^u4f^T{$ z34(1-6*FD@(zRs4rVEz3pS8hjHedpc^(ogQP68|Gvu}*Nz9~5E8Jk+E;A5zokT6l45&Uh#9Bkc zVxBw1#!ZZTjmkIs8SV@q)J^Z9QE;G)j-C&i0Kt^q>Ue}@3p`K&PU7yo@tZhwF66hGv8~T-FD?tcJ z8hW4DXK1gs<6An#C;amB)4;_tFSlbh^_%I>u3Pz$ftrZOXeL<%m9o$BoBA9545}lf z=6=^^)tQWnwmo5VF!%K%|AlaU;z9dH!(=N`Q%4@-EArD7rE}y0GwLc-)u5|EV}<>r z2$M7EgIVy~>+(rqpSKJAb0JHJRO@_vurH3WbG^bEu-8iT|7WO~KCfUZ6}u=ax*r2F z)a1!T9W3T_Wy5>?jfkY-$Gd6U_RS_y|6An05Z4za(aQM>MoLS{vv>m53kU9&;~+{9 zt5wnV+sA^5E6V_j5kOLEc-a4S2`eg5=n3@6$EP=GMD(3`&-d;P5u3mt2R{5%5LCA5 zYVmA0PA;y@%`+O=XLwAi)Ma}HyF3=9vs<%OH7pD{1NVi2NOn2!x-f&=nux&@sL6mZ zup(`_dvP(z_@`;8La&0 z0I&zO0^{|hU*$-NsNVFdrnh!Bm4VZ#JW);l)^Ccf)1o-DgTWznDo%=gB@uRGP6!^W zeH8B|X29EYGI#Ng;}6nRg}nRv_>oX>|XtVT7XcG?>O|?6c05uh9v+B zG*}xr8aU3&5vtkw!*kgd@WI^DrlI2rljVGvvAv(S!a8`X5-%;0>Pq*RL2Jl--iNvX%6aTYe_Wv7SxjrC?T zh>hgJ5I@dq6{p|*qW3>vGX9+Fce0e+WNP&ogN9|td)+Jm$|q^r5XWHF(T$wND{*15 zCEw%J4b&&$hIL36U4qBj=@Zf!H}ES49~k{4OqnONN{&LZ=&c1EGc?6!n& z(W7cbU9*rUrn8_8jZ>kmOt6oW?}{&N9gRvv`r&Ryvj^s6Z#6ggPRz>k5;p%z<_-$x zlqW54n;o#Y!6p9PViGH;MH6SSRKbRJRp#>L!Z?O4%p4BMM4R`kmWQm*k|4ntcUnmY zHw@*6tg%&ukBL8>lbqS%W2voM5NK+XS5-8-P%HQ>BL%I&+$N71$@u~r%o~x}D>81h zyAq6!V5A@IY3ONmxdRl;ks8qNz}m0Be?dG>((6hP7nW}EhFNQkKsV@0FbI)x^NZW@ z;13Cuz^_>4Z~iuC8ewo4z7svlN+!>&ze~fvM=L%{pB8EOYZ^U8$SsTZa}(gxbY!uT z216<~o^NsmPe$MSD@-Nl516(#{%S$@`;Jx&)3O4yqdVV$>ho6KLG)lo*5N>;iBM;XCm{pfP7RzQYpQI(D zpIR?o;$t8DC=1L+nH`hyLf7mugzUI1k98 z(U|y#a-=+6St^BK2 z{h_)owqrZvK6xt>nJ!gWNR^j-r>i2(!krV{z|}>?P01NxisGGZBgVhduO>dv6h}i@E*Te7yIu z(!1b@KG&77wy7u_*9biW&(x-TVelxrjs{B~zGHqAFQpWe^Byo^zV}zF;quuOmx%ciKI%SWur27P~2sb&(3$9Ma)&>;iYMG zOFB3q|F$U8mI$*B6#vZ|KDH|3Rhe{diB5jP=4n#pM6P9K#}*u(+)w>MxBp|})I5Fg z;q6h~4?JBm40U|gXd$BVIC0&GkE5g|fmX((slu7U8S*2ZKRGJePz`f^5Kd&3hFG#U zzl$@u!o$&PJVpJ$ham4R+$*jLmez6Ra?81O4`Ay!_&QGB@)CM}-T>9vzKpt}L-zW) zQTzg=MO>6kD1aIju}GT+pso~{B8)fx9xQi+NGRXWQ~2;Czi@4eK$EFZL4yvfH7)sxMC?)8!7NqmRXtwJA2$Id;U~ zjg^rhIa^~)7&``Qti2%P;cb;(Zt0Q9Np)8U*17p$fE8*N`kUGj%sO0V)~khqC&JR+ zKi%AE#c7yVv?E9~>iSeich&gC|Aq1CiMaP^3vd_O& zoHhJgonTWbbB9+4A9>~6Yl@w5MK%;Q_qvJ{{%ghV@T=KfI8n?q;!yZFyLXt0T;K^Q zEILZ=ro@be05Njjr-+FC*p1tPR+`K}I*_?($6oC(p-ov0tdF<(KKqvv$fo!lUC%Q0 z6nj`*_cb+`2{i%ZQo?2g>M#_%|aQ(!8Y-k9Ikpw^T?Rm4tRt_H`ONFVW;K3 zpcHQ5A<|_U3-V$6WU`VJ8;b~B@51*2YQv1Sw4hR3c;2qy&{iOhFxWqC256qG8)l?>Y|LB$vUurB5~Sr>%TY=kpG~IIp|>uA6w&uSjw+ zDtX_L;UORsgB9sl762>n5FKy*DqEPq2&RkV zJ4Z?OE$zBpwr$(CZQHhO+g5kkMwe~dW|v)E*2&-A`}+>=xntaM|ClQmVq}iYwepFW zbG|czXJQvGB_R8^3g*Za{_JbX}qrek4>t*-U($ z0t{K9*I!qK9>xs@;20M-a0X_R39WdoTSLIHt*7-j;d!Ly-DiHqG!eLe+>CuqNf<=! zy+%bE?|6^=F{sah-J}TFwFarwJeecz5MaJYPp$}@XL&pze9i~14?kJnhHNFErr&@} zY`$5=bpN7(rB$<|ybc_iG#i!rF*e_&@Tb}ZbO#aC+Y{VXVK??D+)S$YchC!Pi}m!`pX{@2m4ouR-s}n?TQ3g231Lg~QhiK`)@D zQQh}#r-T3Fy~pmyzDMu7+LLoMm}RrkxdubgsP~H#1uzB%hQTFj)r{ug{!HMhStka^ zcZGrD>*k+TgTMH7mu^*Y)dJP>D>#`>^Dd_h?k2MM!=csoDbP#9xI;15>|OR=YQg78 zbrJeKzITrV`duH!e_kit%P+0CKaBAd8B_Jf#dEc}+SOf*z>k&f?2}_2bug;2wN(%d z-a=^i)i^xATjgOzd}0rUoPW%-JV4jGPUn1 zEseIR)^Eg6Y!9WwnDGvb*IIKHWt656UMWdP5RFH(o%LP~m)d-VQW_iFT)4A?xHWgw zB$Wm(n|&W-qj9AD>@6>t@wu`3soXoD?TTDsPbXCdG$vi%CpeQ9EKD!t#_gw1tLWmE* zQ!aWrj>~trPHeKjMMHS-wA^V&YHvUj^;>MA? z|B(cReJ;9jX1v6ac_cjhNxSD$7mIdhL$ggf`q{L@y05m&3k{}UvOxY9S0Te2j=#ErLiIk`U*=XO;Na-{PkRx#HL2&46 z{#YpTvnZFBq=(O>JLJIJnAjXR1t&6<7zu)u<|j@8I4N;xl9uGXknF9lVlgMZI4&BV zfAQNeda`IJL^yId849A7FS;qxZGC{Ypd}T!EVZEGDHr*N0OKtInoum%lLQ3|r6mZPWt6dAItT*QHo)48bUsb61&MCc|&!U2Xc zK`i^7ZTHjiA&~~0jx#Ag(2*pmL?MEK?Ahu=UGjM|M*|g8&dQbdmcf3eBvD!yb9Gz$ zL7q7OxZEZEJ^fo>FHz*n#J~lv3mw*yvTj`Wl{x;kwz@y;Sf@RjIH{D+`^$2X_m|h( zRu=*K6hdJoNe%uG95y z8<@}JcnIsz51Sf%FSm)bpw5oJCNR_Mc~WGo0jZq0UMzoA_9;>*x8SiesznDu(54C!ue-IJ^lnDBepWVJ`PoF zklKcYCp*>QGCfFl^06{p?Jd*O< zZ^NU6 zCmxWXLi6YG^LK|qWT1!wS8V8}wwUGB|W68pvAP$*f%#@Z}z_0VPT-2P9fQ{Xsg;wAN2--Ry5k)0lB2dgOwq?3oo=wHqRSYLcwVE8mU zG{gDl0oTi~8WY&jm+e*I*A>uNp_~N`zwf_ ziR1TB02Mk?*lNrWq^1^0%dUQmTPXmViJj?#iGOUX@(^LY$f+~FdjriZjRP5#ilU4`D>Z6 z#wG)bKP7BohqnRd?zT2kOjA09TvvuEL|k^TlJYnp$&2DaN5A>!r%VlzYl)s<8SLM3oOQ^6hrr=DQJa@S%4B~^GK z@(A7{92xb`>l07VnCh`0xk?J8qyaVX-d2jbrWmso);WN(+&qS#N%&Tg6896z2hbL0 z-o5&)_(D7r7>1(|9jL8QKC%UoMv*kIr81h>nSG^xzOBx_A~j+aKdhzw?R~}<`3WAm z`c=5xvJ^zf0xuX2TXkRGJL;teD}PZ&l>o@ zCS+iIKhEy@zV0%-eZLAAe7;r%)P3LO)b+gGPX_otf7KB%^nOx&pYMJn+WE13T%*c)v$3DQu^^)D1S5q3%n6b&WS$+Xf; zmw#WKA}$JXB$~Kk@(9l`rU{kk?B@tZ1l(%GuRB?8VhBIA+U%K*EideN&>}tn5fd zV+ba-T=GQA6LK<86*36tYl~Yto?t}#X^b*RwFe)45}6~yIqx3SxG7#1YH9#ulHChT z-A$8@j;>rZGOc`R`n(+gqVC*ohtTC#hvtu55I!4uHwhFKgVqjU%iP1pWkpG)!n*8V zs@DSkD9!6HA&9M;RbZLkgL3n_;|Iqqsr8Y6@I(LPV$X{7Zcw%{GiPcgtK&i!qX_^n zL`%_-*LWgG{ZQ}PCRHx<(1^l~5_1+sffn7W< zo@)u|oaIl?=-gfGU8UNsQ-L6ZDOwi@6PWPbmThge)HurIeO{BVH3jzL>rG~qfD9EV zD1yWy-vTeHh^S@(S+tB;b_j8%O&1pB3}~w0L=@{Mug^Wg#ukdnxs-C+2_?N+mlcKe zNkaylc5CD+O`%)#(HrQFugjAL0mhc2dUsItw!wZi#VpAqTYej@g7riP9iVG6G-UJJ z?&N5Qxnfp7f8*eA2#ElE*i}-D>4HVCyqp(tWK!qIP`_Ux>dNuf63}p@@5Wg zp%9rYVgWOQ@(I<#EplH04$wb|}9MA4<{idBWWGg z%HA>yvAGpHTHVRzTN@h0Lui9V9obNg%z**T;2!$;wuWAF*~Yox#OOs|w!w6TwN908 zxg?ndUmcGl1~rIUtG*IpwLk9HaJ2B}WSOz#75J}naZ1g>TCZWIcWe=)>S95tE`>7H z{gP&8?Vjz5eCzC*HV?+LgDm$V(>whZ;f#)(v7T!sD z5s4{gbiv>x5MnHjaAHIk;h=j`;CygEFX=JLJLeXAvJcu#tI*Pj;Z5h2{b~$xh0&ub zeeR}lFt<4H;y~DBKMx${ZJ){g!WHrs1{O9oHo^yP2tX>tQ2lQ}Q2hybZ?Q%Rm0!9s z6kqtlb|HYnc2y)T8UJ;_6Etu`k9$`KQ-ey(WNfWm|1x#Jo)OC zL63#Snsib*pt!K3UHEZ=ECK1{Lv44o@-q9TX~N)@ErtRcx>a$|62%@ELj z6le*;MXS}V4lD6NKof((78zRmThdXUrwXWa{}3Hpv1nu_OqZx)Q>YatHlZ{Icsx_b z4H?@h>3Ny-8?6Vtt$-heed@}FZs*IZ>$)w~s za3W0TV#s;FPoZ|4Q3g(jU=ji)rTdOIi<+guAue0oWW@w;S13i=YOr5mZoD=XyDyty?Ewodj{U_K^LuUQc%6>$cZx{tw4K%#vFG^D09 zu+E(!%dCH62q6*0W63%7}rh5N+074$Apz{6UhhZ)Y+{aSiyn& zOFQ>hN2nO>Ga>Esk|+M#vUqe3syG9}%V=rbQ6v_*kG zM+DTR3d4W-_CBC_Rhax>6q)=0CZ2%nJpc9gWBOE~DkY$PERq+I@E+Bn@K(V-L>|sP zsD@|ys5soep{JN$yzptyU1OF5NTHP$#)OHLAK1CV2n-D5IZSM=Uw8VUOlr$AP2xYd zV&H^C<+yo8^nhr%xR`UnolO%-1|i0hkN`l?aT!b62m6Qb;)IDLA+a|7{{lZ}5H1$V zbT%#)J)wSQ(4wLD(HJM1L^$xY01@_@{JFK}D#QrdempYMZ=;D&28E+B&Bgm`;jrG0 z&n1;c=_1wmM`5`IxSDcIgw>0rk-(G63rsh;12u=@4ZL5|)tC+T@~FHQ|M7 zTU)*91ATglPqAsBnrh>lGQ$~N!CbyoFzN-`jR?CjROwUM$7z)%9jeYFgO!KoNyLg| zFzS!{+-(g_no8vXud1*W+xaTnkYF}zY;~OG1}2ojX{eMz&u6LBUBA`ECtG>YROOn` zp5e*$co*$cX?G^oL3KPys!6LqlvJMyidh}Jz~1z6Ag|@4zm1opHQwr^Tl!JIc*&>z zdjursYgUJ<{-%WQt+>rLNn-b$6n4Ke{cipGp;QP#3$&a;JoA@W0D*{NQX3Rb96s87 z4?9|T1rDk&1=brI_?8Z%q-%M$FYCD3ybdju5Y}Q@Eu=~xTMR9sEbwX!8)J_HHx`&x znsa!!aQ#~D4K|OzB&?*h?l)Z6t^l}l4CTiT1my?6=N?PEQ1Pt~L;kG~bT0xZbZ=SW zoZ-I?JOJ!hV6}nn^#Hotfcpu)SakcY0@b@(dL$IY#tCCAFqJ?o%QpgNmYE&m)lL6~ zWL+tW_l)NqfS}#Pr3*gMSP}k2Ti1AfQMP$O?zhIM3aA=v? z$%)jKf9&7nFI8w{Mf!*Q^Z$@P{r@EY`M<~?3I!m4TKWGA`2+vIkiR=|qpOm0vFBNC zE-k!$ssqdI!sRpueViBx;`fizL&^x8z5DH) zL89l3RN#v6)nEAA>dR=T(7wZmAudUZ? zVTk>Yf|5ESAx}kJU*v1fkeO^izJ-qWP78T2&$HHq7U}C!0WSc1IJRHKx zGSAA|gQ&OYJk^pkHr#wH?-mzT`An}Gfqh=jjO%G~(yC+t^sOsZ!gAqPfL^>f?}2-n z!w?XLn3uvC-Bh~!*8&fAX4T$V(oMvjCpqP@M#+je)uic{DKqantwN~1l|m?&2_lvA z-b)AC$8FdJd{G}p9=McHo&L>xGX4MNeIPP`_hESd@E)4i)X8h?U%Y2vlgZ1$2Jjy0 z_8;Dxd;g2~MEw5;?@9Ci!+XX&G4kpE;yvlxKfFib{oi>H`u-o@-?09h_iCU2;=P_L z98*Q@|HgZfy#FWf8Iu10@xB9`7m#iaQDk(9t?xqb9D5JId$H6Ga8DpNI8FfX&#?vd zKzR2)sI^p9f50fN{s5SGrgVUF{ul38169tj5&xU_KmS+WTb0xN6WJR8Qk90PWm3)yK=5a|f1*%H%V=Jf;iZFs{qxiM}l)vGu|});YB1_;}JCD}d^_Sp0(V zv3o(YYuO_4unhkS_JIL}H`Rstw=;k`8q2g?IT~~P4-QBqMk+X&Q7ylq=Gi=yH3mEQ z8EYXuQX>oCRLFh3h$Tj{(>*Y#KbEh`a+B4tOPs4Qs3TDuKy_7PBQ72#P5NAx-C{e) z?m% z3)rs?4%CBUIH19LnC4T1Y|{`r06)cCV3(lybj9XC?M+I=@uK5Iixh6xWq#*#?Kvv* zZ()TYRCy1oQz^!)7bKU~3b7@lvmz_Vsv>Hmz2uKv)44^!3Yd1vKQ;c~Gpu!NJ~jEE zMx0f(*t(Akl$D;mV73w~Z9jVV4N>!z2B^N!r`;VEEMERn(b0DMmDo{!d@&_zi|#-3 z3+_JydTvgz#9_NWK!CXZ#gFixxIPpd z;MxfhY50JGK|OG6ZmU6YJ8U@oL^=stkWL{c`R>^AHkNkCr|rhkJ+83ASeXo$Q$#GN zaHi=n7*!u~u;mRMt!~v5ijXu|)T7n9nxe97J>_tNEy_7^Wb5N{A88{1ymek|xY4S- z?Z^}`7$ONN#9LsB^82n|2ft-qI30+pDJW)4zJE16rXRc&&d?o9dQE94v=jX!4vlKVWL@vHxYX zbmG_`>yD34h?qlsjlLLD{%N$2a7fBNy?Y&R6fHzD9Ht~i9aDeMC`t(fhH{gdw2|Hw zR2JWW6RL>i#Ie#!x1Lcs9RUGR91gXX5i}fx1oTVGvIA2ImBMMDsW~^zWIEUgmisOq83cq3xSx3Ln@;Ota z#t9!s#NWu~%T*tPgaN@*OotmoK4kycinbVz5l~_3HB6KUwB2m8}o;RzuPJrPv)d+UyK*ESEr6kq zA3Emj&hw=SB$mQ4fGi(~B7yC=cNiqu#HK8wG_qusyf#0D3SLQ{V-F_BML)*Fbckfy zZ0l%hF*HcsynElKluul|`t-4iUfeG9){SAxu%*ISZ=QJ%=VE`SwjQKc+%KCYUPOXk zA2AF=Zvn=QqxQO}MrPjLumNMo*lI9NaPvqVRc3u?*D~xeYyNmS4v}+Ub8#HXJ4_&n z(&2*nf|KfKw@+CKZbV^5x_dkqaEW`S8NTCe>=r~ZR4W34zT;nhyh<@nz-njsBKOzy zAk_&IP%a;j6hA=*6PPIc!o!J{E(`3Z{0yTsTuDJvyTqR2M_+1QDPD3{dD{qJqPs_# z9x2uRnPGW}Hb;miY3MYN|}g zWLG#wycuM=BC*p@vqf3szrF-5WAhw&Qrhz#$#=VnL;qO$gTvDqp9%QU?5+9{DA7E3nMdwfvB&jCQ>iN z|AE2ZnE<4hY=e;u30c8@Be;pKG+=|V5W^TXGt0CUAHi5}NrILW;m+j^J3sls=zFJW z9tu?|!y9Iy8wQy@%zPKKqZND~A+HkVfPOU2m4rG`S+XE(;=s%X@$lUHEw~K+vGiIq`2IKN_!GLWgK zsSFW~{toURgcD9SECn?vOQB6z*9hgFaS;XWh6=ONWj%cWw;HAk{AAy6S#VKM2VVE( z3Zg*Ux*f*(n-v+5PB#pFv0Tlf<_OlVBB86rIse1A;jL5z#jA;_ z=&Nfw@|P&+4LEViK1kbI?PR})KT#a&iGw&pLf3&aM}Npov+A*WB~0HIpX_8kROd@-+zz1!&)XyCF)^ zT!+WI^uRlkxB9YX6{q(m{^Dy9#8|~X(6%YgQ%Eo09zjpmhC=?m$2m5&fCYMh?P^Pu z#U6n9X!ip-ZL3L2FwY9x-}+&_5e%g&}S6pmpfN+MEmuCg$nb|PI&R8*#Vn_$RTc!DdZ_YZ*lX-sO$ka3MM)%mJsTLF*zbg0 zQGXTO$pG`-D=ThU5`F$)U!JAQ0INTbewulVmkoI)+Fd^t|Nai#Q>7Rh` zZc|s#thC3%T_#|{ZP6aD-xXqj+jTotsi~!i($3@l>@j~h6YmUq-y!E%_H0Jok`!zI z<3A_KrMAIH*2uH>0B~=&`l96Z9=Zo~rzWY)kOA?y?CK`|E}h9j zr~R-;$j&-rYJKb5qreLs)}`Txt#YDL^lTF;VbNz!lDlRX1Itbbmd(%zPJIzNoI~5l zD@ju6^RB{Xkj|fq=j=W?#TDPVj zU=}*(mPG<;U2S>QUvnW&c|k9XS>&^dwp5IIph5=)O`WIf)hC1f4^T)+T}eLtYwTn! zj%KJVj2>HQUu8Pul?TRODhXTNV@9?`<{la~_ioc*M^uK)NQmv=P{8*#?$0TPG9xtZ zS33IVuo%R9#aMOk!|y0v;_m!Mp7}=|n>#n`F@MuF%%@%tk#!0D1~t7Gpnu^*~?B^8T?Hqo9+ss2+Rf*8XQj+ihs6W z5O=NV&CFX=pE2c@8D75SJhFbDyPJ+~qu%9a4G=$i(jwysYq;1aVfeCVEc4=zmbE<> zyy(q@vCE<&@@4Uvy2D?D*b_B3R5kHydg`6~o=Lwvtv!j~k+CGY$e8%Cyz(59e~)bsS&uHQJou7ObkkI>m`5NCd5ovB z?F~WT38n-v&^6fcOK#YV8T3xhl`^L^@+B!(nS9&{>eW*5!} zi6g65#toz;(U+iUYhwI%Kyt9M>wJZK)v2&8B=y94DGyCyLYKAXb?gOl(^=(C8po^K za#*fQzH#6wcYFBI`ypd&)!@UX&BfX0D2||38l7VW6qNwl{~_b!Tp!iR1uK=$$5azD z_v4DQRm@O^kg0m4gEn&KnPj?F~!;~ zkl0r`ja^}{UD#!W6X{H!2t!lLCJUBaFJ7?ap97G3=71{GU*B+=#Yzt#Q>dq60Yz12 z#e&}jC`kpa=)+LF99`qR8OFH*vtq@s)Y?Zz4_&K23+tCI4qpqMaBC|hy+}B{FdOd% zl!r421ur;6K9(=QP)Ya>b%(UaU!Utkk$~N%n!t-ZgVf1so0nd|(B31L z;*!}i!G3f1iQ1nq>!cEFO!(zrjj5BV?;u#YQaN>B)4U~^{EgXKdqTTAQw}~8PF``! zGlQWjzR#-8Q}OWI;TLo`+%vuwyh!6fL}nj^&Jgj1%jr`DlN;`;#0O;TXAYqUcGNc| z0L}%JUhKmEn0fA3mgh`>OwN+4Nd&m)0SiIpQxMuQU5KY+d zVe{VF*<3k%+UbP1Ondj#zVYQuCq%=O5-A>}X?|>A};>IOX>d9{|x1Slwb* zzaX$ST&98X?EolY``y*`QumSfJz6*5WN2xmC}_6}-~0VEbb*aod68X9ydGo4)3Foa(TPNE9ow1NWQ-RVg{i{+m~i{%*CT(m7zollgt1ub7{iaLfZvr=DA?3 z7!)S>HW}>V&6L#@DHV1y_r5XGf|#ChVgTI#&RIjmzQ|b|4?UlUf%xgQXwc^f)-(!n zQ}lPE9@thtiw#kx^#>l+Y!;#n#aq*0)|>&P41`%SiyJ*FYE5tz&d$drWZaI#O{*4% zW1jB}hhxAWFUvvr>SrT3UX-s0*1v(^@}!rB;ds*DAZH$!A@IgiL`(VUJ$`(PBP5=@ zrk-$(aZt=Iu#M1|9oPdR^-d!Hgx@+HMHZq_3b^v_r2V9|UFnCJWuqb;Kr)uCCo^hk zw3$ISWHjFc)a1~L0%OSZCD=4j4FVz@c~t)deK+(em|g5^%5B@gty6a4q8L)4JRs8b z=eoU<(`9@oUE(iF4ePNOB6qccgJ*9UVltY zD8%)vW;+zxl$YTteD#>FhQUJW$qzz1DeJsjXCcUsEn52H-tnag4Ch%hq_MSLmR%5# zkNw=D8H@EVtpn#aW{hezeIQ>kh- z|A;9t>Q7N-Jv>sGFID7nINt2R;Wu@!&EZGmZHNS9KXn{<--WOe1g1ULO(+Mg(8nLs zl-iW%JBE|;_8O;(t--NcPM3JHAkl)5&n;YsnxN>Pvxqj!J&zkpJP~t9LzeZc{cLd8Zdt;ZXZsqmcDeH`rNt8*k z`1zMReI3bK@MP1C$D$_(Dt92-a1A2)Di)ugVgXQ#e#b#j8r3ZIBT(LP9ex|1ygr>P zxgrrSnPThL&4tWgT?c{Pg1qFt=2*;i-1CvG-Uc+-zdSK)sat8i2Q(`W3VY?hl3%H= zh|awO3wz*3zwUbj9&TdlzCQkBe0zG`8GL_CXMBGae&>BZEa&yUJ--q3zMfYx^nQ$b z+?-ERim*L{5=%&%|^_I`c-5!l-d@FoUW2y7m9&8LGP9B510Ir9kI7ol({@NKS`PNAQ0XCM7$h2JZCw?bzrQTVfow&d(=~m{pO7$c%V60 zm@R}``_mW(3flv0G|mG8m^BG33GCWPfWju+a=;>bxYZ*L`)5+FD*6&U-l8mP{UcW} zZc}wmngg}plAw%wv(YbAq^n~k7MMlEmc-%`56=hrZ}~Hfob5+nB2G9;*ZsnbYJrNc zN2~+-BtvU%)ZG}_M@;E{ZeNpxvg5~nk(5mhb4cVLeq%~oJB+9sByzz{C6>t~cTj{9 z#9YXJFUHcnJ8$LW(hHGsw&yB35`zz05fw>)mZ67js9?9m9ti(iUt*zM{cTle+F!ZD za2Ub?!-Hf0ER85^z~djm_~ky{nDxYX|GJ9yV5U}OWWbP_DKb!v446TjeGvN`6OgVq=ytH zx{2tzGSgRXmR7uBhgYAsD?mH37iSmsMtV9%N$p+?wEez5y8jSD?(tSxY8qd_r~esa z6iq=Qx9hAlq4Vp-JZm+(TU{}j@u!-`OnxY>?I?bcf_;l-!}0+3S69Mn-R+ooIH&UF za6CMdWKbO%BMMdmAlr9<5%z?JpR82bPfD$lzG{>Up8rjIGwl0dvGuO7v2^4t*pKZ# zO>?b38rWC9FnAnr4x}XQJ(TtHuY|X1S0qiJ%~{1Z6!b!fWjzy5ajKT^Y0x1SDQNa`Fca7#hECD=3J5A<5g(}BNKdNJ?Ke5I zkM4;~*Y-;BIX`gm&#T=};u#+uIn8`!lK>fgLE50Pu$qf%gfWc zCw&-yc4IPYGCy|zyl^5n{q+;fi>34|mKay46pjUf3^u|N6?Qdd{kw}HgVO&N0w3(@asG$!YJiJ|S| z>i&YkyPv{m+nVG8p$g>_{7u_Z~ho9U&DS`otqk)dPqrQ?qpRHZ}@zW3|> z@M?hP-F-}&VQNjqr4{jq@vj`d8@kH%F%_DAOEx5PL;B@o^G?lPxBkk4xr5s*fhUsZ zfbur>-K&o~pV|n5>`JxjjVb3ncipMY=!!>!-Z5sqv3Q%W`t+F&8Pmt%Pg44)rNAEh z2OF*C<~7*{P(8{W9fz;f?!_#vK4`z)eh;Vs{k!D=E2=jiav!GpHH^WVs=Np>zvlO{ z(bc~p`~H>}Hi}t4-BzdFz?$*#Y(D!gyw9p&*LU2 zaS-e1cRxSgtGWdeqNq)>hsLH~G)oD*Zms0pFSY$lk#RDr)@r_5j5ltDK~#oOl7scg zP2grF4!ij}I9zp})TLtb2AkN$7#92>o@Z?B0z`^5aD4&+6D{%N#Yi%JdtY#xA8_$K zPo^429Uh2svD{{2H<9A^nkV=mO84}LWC?>o0H5~5COaCVJ1{ljroe=uc5~f!D&R!v zm(zT7j_-=Pnms!7Utx85yB%qCkb#~hq1yb!33b@D(bdiv#Rml^+k!+l6fLhN9!a#$ z2xbP;Z8_>57M1ig-KGoZ`+bu-Ehm#0xLYnsn%Jb$EUjfgwj9}7j2fyxcEv?zf~%7) zGB~5Rnhii{dnL}; zh#w2WFjXS@L7AQN>lsy}8t|i15R3>s>R{sACyuLdZVYrS+9YzOiB|QCOp3Us?TUASset=RV~n#5whPXTeX{#NRd{8C7*YU0@HCCO^UP@_aX`mM`y z`XMW}@UNASNf)48Bea_Q_|9S@5qyMc)7->Z1m1+wsv` z$@8arx;|(meI;XbXM6M}ZK$OtUx(_x7{UAl>;^w*gyInEFrdGn?%fDEpykG4C!3Y} z&V3~V>kF{TiuHKAD({FG5Rll?E2Ak@+jWCG)V6vI{SC5@Xjb1bg6#HKxGuvpj%9Sj zGjI;)ya_GPEI6U@#wv8YwuD0{amGoUqu(2)xaew$e`O_5mD}XftvDl7-6oAkLGjw-o>X1&v$&_50zl%To`zdx?|;sz)wYaF+Vxw zLq|nqFIvKN$Dy4|Y5QGWQ|8*&!(8||TvOTt<%di-Pf(CNQ%=*+26}E>OXh$!0M`Uv zOaAAzlC1%^nRnypV}6c%@K7>yo}$gLnFSEelP1yD7#P5ZguCz~;UfqYJP1P%w*5%M z$WiX*)=*>`%t&mFUIcqUopbVrJ@Nf{8ter0D{|CvhGO852<&0)4HU%cM8`ouPeK6* zuLp2GBB7Q9V=l@QU`))5zaTC!=X|+}qDSfK>%RXp0YQ(FJ|E={bLLgllXs~y6Id@E zXsZw>ve&_R2VWLLD4LQs#%MDPfv z6vIS<3s$1Gz$hAvOSyEq!Gxa-QI9e_oU>VZ#z~0Bq8$q%NwO zj_`~alm{2a>*=q1&z4v@KPIhhuL}4OwDG@NBC3bhc$^b zr$@*RcqoX)_)WU3(Ug1C6(`N=pbk~zem!@#|CWnFBg-8MRWD|DE3jLh`^D*6r7FR~ zw7IRJY~ixC*;vU9W~~^I$V0oSKQmZsx;p~fTGEl+`fA92t{T>cy{&z#H3}OYZ55~C z{k!%p{RfkJ5xS8?-7Q;l z_;=pA7=9s}SUgCxG5Wb0qSyyk$Pi9lSJ16_P!$?`jY zisRm%TZPNYEhU|~ARDbGEeMWdP0JXTlS1$Ze&UM>UJ~f*f8d6Pz-zpFSYs3AaRa2( z6R={I+1T^mM(*~%7l&u7aW1>6KUy`!!WpNGwmUyvEX77Kh491x>bs^H%%A1 z8Rr8pn9ob{lp?**G__YwlkwKhb(9Tn<2*_~1Ksa>?jy9wcAQ^+?cTnB9Dln0c&Ing zD??*fhSmD`luB#T@}G9a#e*-mQ0{k*&9caiuoYBm>ST3o6k9FZF4hzp7F~bNkiILx zhNhA(y++Y9tjg>MmGuid+et4yjXO@iYg@-;Pw0H=Ad8w=$8|gc+*CHPt*^SIVTNhw zd5W_cyJnK)aJ354G|2&{$T*~0ZdY8NfygDN{jY<94A;L=5G&^rvs&u)9{W4YD!dJd zUpq$yQaB4~zEv*tzl{n5yOf+qcvolXWCMt%&2Zm-Q7s~uA2a}&eh!HJhxE)t zd$L`MhxH++gvZPQ5wI1M6z@kZn`w_k=eH^p4|e>$N5D+gz!PeZ zlhWYba!V=6jK({(5fs7|NvslUM+hC*c- zFFgZ4)QOr%desoo?{!N0Wc+FFb&__e0VhDQ?{(scNqU!GK+t=a389>*?g0x0F2*#{ zUxlqhT5i(KYR#&m$68?ku`=3Bx@x*7!jFz#-DG!TJQe+ILCdN(iS+5ycj03{yw`#O zijMNKs{YY7G{mK35-SQj7a+Yqr*)B)dcF3f5hHU>2YC8{t$y^eQT0E+V79+%5Z;!` zYyDSnyZRyDPBCC~!lJDPVc=wm7S6{`rAsSSIMkBn+5YuZxbya9mmY{QJnV(wj5*^l z^E7UO8xc*~L3f$9lTFfT*|RimiRTkdUQsePZp8~2I=yIc;qk?GrsrUym{uo(LRtR5MazR_K%`-im?6%KY!8M$_VQCt zs1{gQ67~NYMh)r#@s%}=OtsZdVb(cQ-6O-IhR1lpdv~+GZk!qPVV*pQ?fx#6=vkiv zEvGSujr8sRJAm(h6GO5($2c52l%^_N#_Y;K+(Z#;^>zgj^q_N(jQ2cqB1}ETVH)`! zEQ#MT*gArp_F@uwNd23@I;y4k2>Sv~96S9k{S*E6<@c<82C=Rk1T zVF+~`(B>cTVfhUC#SaepJyU3muC=0MCmW32rx>J#K?~psI1!_!2P-v(Yi2rl11MQjCZox-j?mP6|kMgxES*bIF zCjRs~!$mhm2Q+G!{pP|xUjQ~VK>l#R;{;*`ksgukMX$G zt4Y3kt0f@m-ME~5+SA*q7>h+wFo`W?>5AoV9Mt|#-#lvDL@|N))UVJ@)=;qB$nH@;pG(CDtioj zFhiKEz>^qE4HxPahUo?&1_P6T;m{u#^SmRPw~CQb>}GI!WO{~kHqnOj0&`K{^2yS! zAq#Wlmb8h+1T$8Xgt=FH$@(vM{H6GBcWiO-e{;t}TI{x_HFRCaR!MV8eigJ2;aOs} zn^}VxOkZl%R=Dx9=ls&mg7}2R+Jvewq{iWZ4JOSpaDg`Ae&%%r`j`l=D$Eds7VbW$ zt92*oQJ?&@2#4Ubhz9{@pvI;`Ya{2gFXi?Duhcm~XB`c_z4NNI;RL(~XGp4Eh5fpU zk`cULYuh;5sW>zof9|G}S0L(Y;(F2nc4!#tDypZH6WMSY>S`?NDkN)hTRbtzu-gYv z%mMdMr1*Gl$y|GK4W$cN9oK>axCh+-VC}7g;t0Eb!2m&mLvRfi9D=*MOK^90cTI4Y z;O_3h2?Td{cX#*g*!zCFd$+dg*8O7!W~!l{neIO4{N$WRIm)>KT8XNZrt`drDv@H7 z+XzH5$y|r#T|55h9Xz{}bv!m{`;xdL!=0gH?c*6lrY@>BVOn*{?B=&d)iXz&Qwnnw z?93(I3wh#R(wYk|j>YxGPghL_Z6#v_iUwqA-Ed9(s3mTu(xSH7gG%a;ZudjRiJzJ5 z88HT*8j=7H+cyh28OAb*_?j7N{Drnbyi@zC*J=Gxi#EtkPo^MIt2{nxkx*t<_~Vuc7y|@QQNc z+p)h?c{YRH3Esi2q3^Qza4c9m!{gC;gRK$1f(F`k)tu;E&f!MR&4BDpaYC>&ePhF! zEIN0y;B2)<4_hJY!E6a^tcZ^@AMX8jU3~SEQvKwxrh#Dn z!W#$f<1^P(nWpKzsRqc*&;Bk)Xm=h+Wu=X1SK0M(5l?%myJn_wdNP)R6H$%alTrH~ z*Nv}Twnn5Ze zbN#G|72T$xkHQ)??WrLMY@k1gwh(H>A7Nw9iDHuC9KE&Q%W{xd_fM zY>KDP-m1wo$WS-cSq|SARCMiWLshJi&FNU_>b>n+t|=NEJ0P~K0eIZDS_V~?Zc)Aon2$iZa>OeS8(g9%k$8a_bI*8jn_Tf zLmvzn4kaC_D?tP;7b7+gAA$j2j`vzdWAVA-Yh1-m169<5O2P%6e)7ko%dh1Pz$m!- zQqUSGxDtTEDQaN|3CE-N;A2#@e45K)-@rme&?I&HN<`t`AS(+$q_F#nb!;LIQN{Iv z!Ou~UKIr-{o_Bd8m~|4^^E`(~rr_)Z20U(k<+9b=m&KhcDS~ODHz7`XAG_IhScj;; zJB~t2zy-t)RTkI^Cdk;Hnb8XG55Zo@>uBu5Y!00f)B6#DT)NW5Q3k%zC%aWdn0gqf#;!nN5<#i-F?3oXg>u$ zkZlJbbqPv5fNUF2TEeNi%}_lcl1WhV1Z3NRNS;sS>k&#V4n-&tDtHnk8oydXXB;u=&~tVi0B;B?=mF>JONiHu_s0LcQt)7=ymj$v{O!MCFcOR9iiFXqHcn zZXBw<_N;o~D0LH+1_U~TN4|lvMN?=cs&x`s6a0DLbeB?ElbMX`h04(~Jgcfu2S2LI zd9dhm^3~W9n;i)ZfZ3lOY*V2k1D6b^_Mo%CYG8IfboQYC1JUoJN?N}o!WAcZtO7rHmie%jJ`N$X}BWd zwGk0v!7F%!p?Cq0jg> znyF7#Se1PSiF~ybGTR{AfYGfNOaVLvJ`8(**Fh)f+W0r3!z;}g&^`r=e%_DeqB{#C zyQd;!OZ1IBl6uPn-z#(0)x_}oenFUNExtJ_cC%z^T{Bl)tge}PnGxYpZ951Uwn`^! z*q}i0e8211pmYIY-jr?96E!c#sE>#iVkGICkc~;69G#8H5MmU@D=;3G(?^zU`vjuw zYa9_;qdF+30hnn`3`lWRl%O?F!d@@CCO;XvD2$IYeI&w;c=}illRwa+OniY%(e@>x zhJl+RtkDGbB&3*H_m1|+WuE#NA9_e^2+oOfPGLQf?v}_JbQ^%dRcZHo$Q|E6j$AM>pf(~xo zGc!{4?oenz)z-h|k#SOyCLzk__b!~N+kGkOlmq$n}mdurVA^z z1P$8k%?1`V;Edu0Yi&Qxjn=+TDY+kY`}sY?xxg>FX0B|6tz;7vm4leYhNr2Qc-UlH7LX9`590V=Hwzp#=KpY*o4)42 z^okWvDwD~CH9-=P*Y{K{_Dk&j@MO*;U)zet&mH`mw=o| zFmquC&R+N2^T449#+MINx#tD#5?DN@Pr2vDx#vK14EILCG=17c2urxV5pBil9_hxZ z1&L3n#-mPJ3)NrlhAkq1(_)A`F_={F!{#wEK{d)#E$loBURnV44_QOI}Kp3HXI*niv$W=wnWwC=;f)4rfDonUXx}2t$=8&ksX! z8@k92BV`#*kI#0cc!i^T&kUQs>t3Jxo^(7?GiH#Y@?85 z7ta;* znvw<&S7Lsg%^uImDBbDBmUim0{bC@p#3$+`SWP566m=BTq0%2A>eOW;X&~b9#s4U1 z)Jh~bz~Y61l_XnTBsT{7KLCuW%8bwk28YM@eaRnIN3---Q+7S{#qpkNceyT=|74wC zUW`ne<$i*6a-<^n!#v8zX=uw9WPjIEk+0pkS$j7lI=lRN zLcy)7Yj^Y5np6L-NBu@vN}3P#(-^j}W4{Q-Y`nJ)DkAH52$Y%}e~$qHuhY0mUV`ek z0dqVu>;$T$GWi7yX++qhBz7#vUAM?&DC9s^S9m^W&ELq|;#d5@@f?PFLlhjAb2=#$qv)B&6Yv5HwRp zggkrlH;{DKDOW*igtYkOwfo3u;hFYA8=i37I(KS2U|fS_4+7n;K8ZbBZ6E(azcViJ%qHU-hc{wrUQC-xfM zA>^i6w>~@Ia)CSC0ZYQ?Zi@J~q%#*$>}TG=Ds35utg-W70t&Z7)<2PC{d~-Xp?%0W ze798ajT>EuEQLs4tvi9vu zXttR|UnAK%%`Ty{!$qyf0CcRb{Va>?hjk{CPO~jKT!593mY$40Qh8HiZ_CcOR~x^6 z-SAnyKOL|JTo{)7n7a22-uWrmmBUSjdPxzw#af>=*t$sO%YE8(wtbIjBUo++Xb4nJ z@J4}oi&5bP=$2JnTbqUbOp>aHe5~39P8TaN1SIxqBDu9&fAbbDLfEX8)4A(PyGsW4 z?4VsKXX;_~;fePD&=J66|Dz+o70MKJZ~S2?Zj!=idZ0VZm}$lr*pSFCq$|u(=?T>N zs1rOnu$R}(QjjUdID_9&t5_6IEtoNI*zPG6S&iy{FR3^j+G(gaTnsgtQyl9Cje776 z06NnYwG<@HThg;AT~iQH_c!fGYf&DK$mZIPBH25A1$0$LrZsJB}A z^R~z)O!B6tQglJO4YmoT8?6`Li@Ej*DAc2_?HQGIcHOHe^r65Nnv$+lJ-4AzOLVrg=WH0xBT54ry4J18Lo75CHM6b+o zSN)%OgT89@3*n`u+XDzsKWwqi=EPaVIi|@K$nQ+9j2;ihpWMlcwsmrr|8`#0R+%uBZMqncxi)_19Hn8-eZlUDHCpw|x(Eh`=|hcC_%Zz->kdTV$_fvS}F0RHEKJ7h)`Ad@B^4 z>V@*ITi~A{btZ&`jQx4Kbd)(n%$dDgc<=S&QA#arAYgZxXI`@mMU-FRC1>O*&r3d zdV`0U2B;Mg%V2W!a`afOn;_6x?~-u8jse*hF&W6dUjq0|$i95cK}?2XMB!%$3F9~E z!M8Est_pC*r|FgzhBe&09?r7+U{fF)PE@G2+)Nxr^8Q#pOFhUc@gWa9w&L7|{DS}6 zTCR0(9=nd^9L`3OX}DDXqDQ&GVpq;m(Fyw3f{LMGD#eh_Gn~7nz9v&C(jo!doJFi% zbj*v-0R!#~vYy_1(Aw-32&R+|c;cZNDemqEFxzj8P|#U;k4zIOKMv_|ljVLA-)LC| zOO~z=_TV!9T8Equ)-BtG97;q+Fo8^mk%Z6>nCu;vc>5!KK6fEpJzp&)#o*N}>ew6O zx#?|6jSSE)6f@w}ZU(m>kly}WXSI-jv-Bu<8CIiQ!T4DMgW~&kc#QL{YYFRtVS0CbvK^`5X<*6G{e9{0%?Bo^@gCZ-- z+=H#2HX?W|Fz#m!0k7qd>VpW(5Apl(!4P$C2P5Bhy$-)KDW1}NNpqi}R|hWV4Pt$XWm6>mqW zJ1>C`0KpUM{z7n;dc1_HV0AzUXaIzOng7(G*JG1*OLI~|ij_$H&rY<_ zjo=X(L&3U#5Iao(H6Lmec2d33O~&^(@Dl!*Miz4C5#gz}g*|%MK*PGOIc-`Tu6bX< z+7+Cv&BF=UHwY%72%4pZ*074r*;dOfxUetSQNWTM*i=P`=}P`CZC25@?PKou!pVpP zS5-cZ%Q9|NC>Ey-qc7==W3si-0F1@d-XwMc8*}JX*DveUuIM1sx*~tO7pbzohp9k} zoHiO)YOmtQHE8hU{{^KrD1*|3LWvjd=T>K7p=)=2op~H%HLuYXuDUkcd@*RjD{RGv zJ=MeP_`>YXbr4k~1+7cXo3H)ml_YOU!H=Rd+(7QetRmFxt#b?XD;U`3tY7dY6oeN_lZ zgpR0xy@bSM9#tOr$>l_1k?#NfTYT!}S}}hq&XU4H<$~I^ZK|Ls4|Edlz6hU+D37>r z!WGd(q$tmTC=XEfK8%ymPek_MS281GBz(~r{Ncp`Dc6ULP0WnqJuIQ+Kc)e#u|A24 zrk)MO@@a;=!<{5a{)k*eT*FP`9ar54i4m(VVRCC6uIk>~39a&NU zNeb_`czQ$d>jw^<06jLOK1mH-Qg|m_^!yzXJUuqgk9ik$`&e<3*rM$&DQW}8p}+b> zDVEovyJaR`gY&8dqA^EM>DL)X|DvMXIia-HuTvk9idRap!VPgN`Ul_kVUdI~CQg;! zZQ{RN@?2bBd3=F=+#eUN`)Z0BM`>?!g>!5NqnIo4p=H>M+}5_mWbmp<79nDE4Q7og zgf?lvY~HoA)(Xu`Vfv%4Bf?%teT3*wv;R=VH%Tn>7(sKr>vzFvbAPotmk*{Y;c}8D z2~XCp&C?JAsSo$#RUG&FBIu%jwND+?_T6gv@QOL)xSqUX^}!)-MLnmh&%$0~0ZBI< zVi-IGrJp?R-@+}TWy)PNxzP_BGCp=U5tmSV6CN6JO&k_%#`aj+%ajl2@R-R;kiAZ6 zZupZc0GlP?yu=Nwt?-bdv;c5Znm=;6{c|Bt>b?VSEl=E0QY)d1jfuS#G(~{==<{#W%tEDGdU^CMsP>ST!MVOH373STT3Rr?tQ> z2(q_B&-60Hock(#r(^Ys4-Z552b|MtSvTeccL9j_Uy*-vZfli@zP|lDmW}S{PfSSB zy~XtGstca!UAr?)YxsM9Hx^1TKxl-tI*@ISQ=rKud!KsC?r7c$gx>*5tAb>b>&rX4 zU&d5_s=JZDp0&aOT><@l>F@r5%1qo_+XUGFebuh0|Q3D$LcceFz&|^&rV?FHC_XGn^Ta4ZYs$ryd)WVNpeS3S2kpQH;nNKIP*#J6>To<8c21E%NZY}y z+mN`MIa{@P-$bDXqOZOe+GZ*h>GA$J{f%RH7)Ug2qE;C0_9vXifBz39IH*^YU3d>9@~Xavnao>$o{k?U_{mZSxCuhB$0*@tymV&(k!zMiI;mGE>qdAY1B zm@N_aoCJAZAR7E@xvtu(IMYv(Lf&>fS+zPxK?=mNf90g_x!Eoa_b4{TY_kTfh{Lx) z%tDP9%GpfTlDmQ`*-_t8aEH&ChK2LieO_)Ka zmDT)0S-4$2`^C1nXXJ5NV9e`bZJjvM(6Ih*JVip#!*=gL5 z?~hsAib)d=Hyi|z8K|qJs+kzPE}l+*99XqRBom8%XT*Y&jSq3|f>?cn_=ZpCn(n9l zL600mURHfYcKixnw4a{{B@3Bh*MlRGnmOQO8$7E^9umN9qzeapY?zdIvgJw~o{a1h z5T=sRdc0Js-5lx`@hE6nj_f4?m;0S3B%BPuxlWqHe&Mj%X_S-PQ=iwNoW1OcyBJB42J;_z4kGU?Q;9Sq7-aO@8?VhB9eB!@TL@!oLDdSROC@O3 zL0Batij$C?6kpjct$bXJZa9h#7k&GKd8|F8pAwOQhyB*h@opeJ&B5o)MqiVMvNUf` z``kH|qG0kVV4sowNKPitFHb7bSoGte9QE8Y>n|G{S2LzQIO=;tWo@&tU^B8@vLrVQ zU_n;s1%I9whQCvG9Jf6p63$(Sf9&5>mp2a;Svl}`iaeEDhd=}MPFX@X z4Q&x`n`A>@_$0@xMai~Z_Rx@^-9uKgaT+^K?WAnWZ~=M@GCwkc*AFuV0w6;>Mz;)v zSLyoXPeMb8Y0YYBJZZ6A01-{=7ej}9aOVrjd1XX`qaw>NX z5W$pV;l-45#-3xy#`?Tl7jqlk&*e<7(zDxPQBRP;Ag2^<{oBWeE1>ZjpSsOJlEQ91 zEZi)38?ix`yhl2vt}u>v#vPIyO=eOAIp7fwNscAw&6mhrfQvI8Yc@@z;`fQYf^VCp z6FmcyU!y*8W@98z*Ztf=$Oz|rI((ldOL4EEyU zj7vDJ)3;oA-2_Tme|j*GMi2V-#mkF#Pl^c(%zq;9qY~?=`YXF;V#NSOCvky?sJ|_5-B{1A;xtPk& zKO*O&q6inKDyDYJnaD^V5A;$qE}@T!u^SJCAq>X-w@ld1oRx^JpnZm^6yv6PXrjZt z7&eOVY0~TQ>D!eYU0%Oc0jh*#aw7u`@w~kP*yF(H3evEm=3_`CXY2mKy#{CQ_wsyg z1f30-!~>PMjfRv8e!Wp-_cOHe4P@)wyM)#X3bN0l*6L30!yRdH^u}vz$ko%!)Qy5A zKQHG5qpd&h*7=eDh~yt5k)60tsLWX3K`s z_z~#VXRPBS9V2KEDHBQNz%=j9zW>4gN0&@`Z}DJG~G504Nd+QC7&skm;6@s=;voKr5y`1Li?_A#8TnS&*!aR z(S+8+9l}Bfvn3v3RoXjq0@ZKOhSWuQ$l*kWXqerR;i z7+N_RGF`Vz7+V}EPZK2qMUD=&4Jw8~unqdIN4$}j3|*8pA94Wv0t0dzwBv&W5l*Dk z@yr*_xgwW6h(eb=D}SOTvrP-i-fg^q3ETwIoRvr}Dhe7a`&F~9TwE(#2+U^r<*Ka0 zPm!(aOFPgG)L$WnhRZbZKXft~I2belM%7M7*cO9^n04_0bKwAUP%L_lvc5hW;O53C z_Y5Pum zbk^Oo==Ye-3}uYYGC^S($1GNvHnryu3H)kNTT_m1#QB_9TvX7m5)fpSpqgf-ocY_Mv4aI@y{%&0lCiz7hp@H=W-qW~Ovp#Rv z(={UcJ^EZcX}Tjiww^O$RT&rJEDoq`xIXM|7gM3p&8}y&=n@TLDurO+0#*>$@)`YH zEIiW&mN#S<6Vfo?J#VpCKUq_v6YeSQ^12C+CCwK27|0PNUyZI1q9!yR(Z=uc8!E9F1q1 zOWC@^L%im2CuUpuQ)4`+ut_Jgj<@2DWSofk{i*t(-i-*|GK1obdeXI}D)MvR+Cva$ z-+6=|UU|xCSL9bp6=mF!^~Jx_z5cnjhTa=690JmIL&6_KiQJDxbji=>p1aD}O)a>> zcmJaf-j|;COIQRwEr9liVD#7WhG61cf%gpJTnRwn47GrwWC-R4;${e@m8Y15ro?S; za}PBl7rpDNUp0C@`)fg6HaT0@jn5JkP#6)+{4I=Rz!1N>?ZMpk&hTcn)L>_})HK7D z3bF(~#viXSB70KwQghB7cDwe>MN-!}j6x5B!U7wvb+X1x7PuHNiOafaLuA2XtX_gQ ze@Zo=iQyNgTU-q2dXPIejf%Gr!MQ$eAP);yC_6e7_Yek*Y(fF~6dxT3Bxtgsp&HBK z+yWok5lZTK?z$Z_-c0+vZ0+z~3{S zHxN!Rv&rWZ#_}$Dt~g0H@r>0`w&%3@A*Eetz^({*~gR?#^L$^Z0# zblEIW1<_s~0!2hdG={0Qbk*yufU?`wBl_O@>}0c&3Qw1fa}1Lcl(S1!_9kL%3D+0w z-Qc3Hv#K#48;1=h$JogsuuUgqHMXD^_LkNM`$a^ND_)%Q!rRL=C_y4`EGBmTAYG?* zU~|$4M0`XMoS!82U+SYPTDlj6tDai8z4b~>nmpcN;%c@5CvPx;?rdTkMzd{fTS7R2 z_MOSzMR!OTjrI|oMmL$%ZFIa)jU%sCO2Ggd+m^{yIz$|J z3Pw-l6$u?|@C!ix5RzdMJdi(Mb0g04cvq8x0A5Y)wup z7$9`BOnT_faOOOLx^s9af9nkazGE_?C91ql)R! z$nt^^TwpYCmYbVnE-5_2X(z3LE*bA?EV@Oa;PI}^z<8-R>>hBjg%*=%Wu$xCc?m8b zZH&uK?Lm;4In?_q&JDGfV(5`LQDDYToTqNcJo;{ZCPAkZxZQ{BmQb0R@ZsoLYHNDN ztC}yJytTrUv^aS66r_|6?*>N*SRM<1b1!FU^Wvq@gw*#NNpQib*;eqyna1loDKwiX zaxY`dbw>Gg$6JKMS8{#$?tCK(sq&v7WY#UzVZONF%B2MEO7xwR*@z!9H6r_3JWh%_CjBWed| zB+WGR8L!YTfBgftD1AocvMA>Zh`!EcmwK%^c|7@F__(KSeCyD zLXc+~*96}`gk=n7eEsy&c+pP#Jn7?)kHfWW2a6Is0}CZ_`X5j4~D27Xf#WEi%1rg*m$>+7gm{czgfXy+4E3x*A7LWPLJmIxd)F<`c4Tp)d=-#mMfo}j z;;P6M-d`eq3ug5}-0LMyQjS${xBOcI|1NRW9|#fhlR(@X^FJRepA0ADXBJti2(KI~ zu=c;N!m@3U$7E3=P%(wp=de|-RiV@8-++%EF;_y4<|f2spJ7A)P$iOpezE_0Dkyxc z04TX=IOU%&O`LSfp!u)l0|cDiNWe%&D1r6kVU>1W4nux41BwyJ${Jv{Bt`_yS`)Z}G3Nm0bAZi`7>%6Zz^K9W$3nudr zbLaR0&Du}Pn)ay0Am23sYlhsec~F|SECOHGjl8Uu0~>6Xe5^P@b}+qY5q)}tf@AEaJ%5P{FG`tVq$$q-vb5`66S+%A zh^KB)J{$5L?`>&mAar|UtxP(WVHpu@tFNSw7-jx*|%B3h#rLz33}X@nv%`C`KEe$j*9PzStFi=J$=i*Y(+q68r&zO_i0JNR=>eNr7^C)aatoA%o;&d zlGQyItm5xoKLSyH>%&pa*(Hx`Q;@jejT?v)KXP-@$$Ub+iOzaI$2P(X->7X9 z|I2!ue#n^L$=DqWWeDZ+S2r(peE)izkJT?vpY*N`F6hlyDhl|YvS^wc8O9?#4#)<- zabR0)X2P6+SgM1fTnA5qSNXHSO z>L>+>`shDL-;BB4>NF`;Lq8vR(M6HMy`TAT_fYIhXLOxcX!+nwN+ zb?W#&f6EmVO;W<1!#Rj;7l8)7$Oo+d&KH0lcyY`cK~)$!%Oir+6NZGXnj~s4aLNYj zf$TyGwCM*TL$1!Zho3)4k3HNMWqQXE5ifCnk}%-oiu`xMmRCfSy`G%ozWhfuz=F6P zGXE_IF}&3A4Z{#~Bf51AoMJvdtVN1UNBqcW{pjbO62MOR7VPV~-ZzQX2%*v0`#$K( zaJ|37N!HR( z#2z3El|sZRHvk_qQq+vKG7?A_(QP^|$fLf`BeNMJ?nJmVs9a$OF4?TzGKZcU!(f@1 z?rgpxUUZ5t9oZWRMwh785w}_Zm)jfNFaYE91G$Rf69?h)*P)jdlhETToJcH<;W!5T zFSqt(r@7TooNnJ*Ag>Z9=ZUx^PJDp50Bl&T1-@L)H8LZYSVxXl9{3XKZmg@iv*|xF z?e0f4{5MKBe#|3(eEhD)NAT6>XDyoSZ7MUG42fz|O_6P6R}%)%bvS;fV1CM*+o#@K zE*FhZjY_puO=+B?t|6t_V}|UXn2j1L^-WFL%7_+znQZ#Rb->BdHEo{i#C+a?LhXoR zPY*u&=0A46Ll+JKbqLQy(zl=V#Vxx#tB3X&(qI8kDpl_6aLuw z0Fp-ZH%U{X+w1=+r0g@DWSx?jwN&+f9E=sAvLk}xmCKAY`2dYnQzAgt9O@Y;{<%rh zA@n{{WIYvV-P4vH+DmnjPE@(bV&FA>FR>|JIkm%MEUtPP83Owzf%A(5g4p3Q4 zOeM!lbZwt$0G(yiGTt3Ii-IG{(e2?x>f;|u$9#gr%E@lt-|RR>RI)6$e{nNneo&8X zc7XtMTeezSCY;yXi(206)<*%tI5PLi>0dzA5iz4KP1=h!$}NEdY+wTI6<*$oFUEH2;NK(rZ>#t zz(GIN4ly=jcxPt1K{cJ`SXfR!PhIVzS8OT0+x}gn%}di*O)_eI1e$&RZbSwXdJXi& zh^r0bN>bEl2prFJQI|pNv= zcGH_p2qvte56006-PdG#R}tjn@z@7cOF_|dt=zHC=3=*}t-V&6Qr;SHPnFzn;Jxf@ zs{LXDwab-`^An^r&q0xrjxO$^79n`p?G}M{g8E^gwz3qk!nRv9*!nI8G}2>J(%UTp z1)J39#YgnvjULJ6dfgF{;PFd@GZm;LS?iI7IT%ER5| ztgfJpN*hUzcPsm;H9`pl!{TaCI9G2&;h%QB)?yEme`l=6kqD0E11P5ql>b+Oo(_S+ z|DK*5aP!Ae+U^T=ly=U|##T(1&hU3<)PPqYZpb1rE$)si;{bN)_IP^q_DWH@+6 zv7l=p?}zo#D+-PCBR);d#juF4@N9)|$Y~$a%GXLf3#DIu((;a`ZLf^MM0@o7kyC_O zc#S?1vf5U$E6K+eKqcyQQ@Sm$R~R0s&Y1De2n*bFTTB?PZ!!u!9GJOZ>@h7#VYP!s zLi|?IK`d27^g`&qKt-?~#yK|Y90bKGg%!J2=pIR5kV0jynO-QTLs%hYnVN=)sSpAW#QGygPL zvBS3fyybZ*V6a-Sm>>Xu6Q&+a3Vk% zh8nUrxUku_W#@nU`Mk_4TH?|U{`vW=z(jnL2_vPK7QApWdMln6`qV1{KVLH7=VN7a zCuS=7yR^0(!iU7D1zl-(?j1vL)9(7FUVd9o=h3ii5nu#qxF3M%LuomJmqDj2Z%0(j zA9rCsg`h9L_uCUIwQ&HYKnfly5T~(I@q3I9_T=Xek?tNvokFG50r|P*Ss}M6PHV1A zX=;FUpMAP?FwifIYI`H|YWjp7dU6TOBztuIN%_ms#|4RcS>AE|MyE_i-Rl5l4fyI~ zR9>;Pf+LWJV!Z4?9^RQQ{FCNL07u^sD0b3dz|jZLH||(tor_W9tFxJvcD%+Z^bdz`4Gos$OCTC4XYNmXLyE}>ScY6fH=2wO zIz1oailY0&A390dxh%zJD&%P8yrx}qHctFuQ?@Df*9n|RG*}>q`IYQ?{A-}As(<89 z1W>1{;vW<9-^c+Nk{jq{xfuuI95>-(&{0mrsF;{4z@1D$rk89v2Q zkce`;RIMF6njoBx+@9;M3qnE1FdutgC!_G__49no`T*n#iZa zdCWvv2TR5MDl_NFEjS>mWd?NcADO7z9wxn?*t8K4ats<8MX;w)^5ta9mpc0O9S*7E zqOIO;TRxa$qW5ASCuxx$1jjO*zdJMQP8f1nIchOdo3%G&suNRP24mjEU(q}Fny=LQ4CkLN@l}pJR?u>+i zHa!Vh_LHI}hT$XG5Y=9VZ=oFdYmjV@(k9#~2&p>hWIr&W-apP{Fd4!BJoB5+u|H~? z68q?4c)uNBI=JEOlc{-y0uzc%aAv{SStIgC3`sS$qfECCg{V(k(|U z(zizzLj(mQWEbX}K*&ZG<4?#&AF?IND-eyNWPsAIYrQ7QJy9SNUcM5aXq`)C58{k^ zThWjLH8al;Lq6HK5Vx=QHYNp7m{mnV`RK!wB)Yxr-;Qr08nU8e;Hjc*@j`W`=;FRp zP2|eR!i84N{7j(t!DW{pZA+(bOgaE|+oX>_6;8FblOPj25{A0-6#QrWHzW}Y0DZ}w z?sgyr34cX__#&n}#IpY#xw7F_uiAT0b>T?5Z^D3Ks?fd}!C9PK%JGT*O&K1?*`@d{ zKn`)_`s0@!>fZBV8zqZS>L(Zjwoo=+hH|FD_?9Aw&Fa#1HR*|(K+`gJH-@8{YV3P| zbNe$9IJ0-#vq^H4LZ1OgD6G@##1h$_1gpiz?`rEuuP;9$y_{WvIhs3}ALCPp8xp0U z6<@}Gfmx8}-f3-~R^1Jjo=|b-?E;M*&pK#2%3|S^mG}Z4Pn}S+hDhZKt=5NwLE7e5 z@9TrXKC9VU zw$<0&`BwND92U!!Vx>#c+BGCHp?>z4;vN77Y$`=O&%w7Cfyd!nuGBe$WgLBtbg-Ib zsWwB?V<4LLd#R4Gf1Q%opksJtf2>7!&A9nd;dOGmb$yZn zFB2}3_B=;r#cOESgmgRu47PmLN>F~xz)J`9tl2hZ(U~)TPDZm=sjPdGz!WsAy!w36 zeZ7(a?34}90*gZr8K@>goEXqdwZYa@Z6P(PUWtG3Su2TeHQ?Ig29xu<1{hSHU5BJ@ zD{lve+R?e)NoP9zs@d1$EN;`TvM6W0>f-xGuCYK~(ZE5cI6RAJ?;OWW9f;cqb+r~L zjhZyF!yzleZ`!|9vK%p4w?_*a^> zN}1)?KARy46no}%eAC3KX0) z7j>7lw&*y_Y85RQ=fVM+u^#t8}M;OtOW&X9{!4nZL zu{QABZ>fwlrI|8^Z?mLG9epM$-@CQ1S{sT!Kc4GEIctK1k5Bn)!CBaF8Qt^+lbx+* zOt{)kXzjOTUiyu|uyFQX^0zNX7OKSiOh+lQ(Mum;)+UD+Oq+S=rz#lC%=ttV@nz~C z1Z`&PLtl2-bLMlRlHJl}&ww@#&yTHl#V8G{uVmMINSnt0Bn5^tHx`gU0r?_n#rfCBD=aK%^e) zNW`4X_*1?sIo1*9KVWxxf(+l)ImaU=GrGh_S@8!MkJLWXkIHT1k&?>T1A29kyP!bm z?sAR{I{z=y-ZCtbrdbol-DMhgcLsNNW^i|BfWZfMcelaa-Q67qcXxMpwjX)V?sd+7 zfA;%PMUq+Bl~tV`5gGTL5wHAloPxYh!(*t@XFAZ%N4Dz2Oir6Rz024*XYjC5acg&# zi5m@Qyx0-fA5DPr2SE44W0#)C^?;i9$IkTYrhxbLGOgREJDdyurT3!p!ycoLJ8s_V z`U_OE&8|CSd#WO1?$1k~{nobKc8H7VS*@)x7kGrfGKb-$z;S$SyOE4fgGSe4%$1P0 ziwzIx^nOg}`7JhCk|xf-(Dv=rMN zdw7oIb#R$`9+$V3xWwsKDoQp6+|4Iveyl|k0jiH)ZugN0x`vegTrFy|cjo8r-WO)? zoDHfTv5CaSPIgpFkR`F7+6BB4@g7q|YwSmbqwVy|k(6$XCLcCY%MhI`Qf6e@8Vr(-0D55!x&F7|rKKd7w$|yL=_#LWNzE#&9d<=s)9EP_8nm!t+v2yd5p~8l0K?kIgBgI|XI}&>%+*Pqcg>(}FK#q?eGa}8BGPOeCCEyn zt`_D0J%*Ubiwo!u1aJ#^2;$knB#)z}phG0&u=K zUL1+KUI(vy-upkdhptoaHHQ`9$^V65Kn(y_~*!XBkYkoGx}si zNmt(ROA45tuU746ghV;0xFU{{5PCF?VvwJnMCTe)OFP-ZJhR4nW?u0QZ&{>U{G<%%!4G3;t6YPPB%EaGi|%3(3Y|MM}Zga>DK2E>N3TrJ&^PQ)v+@y4DNF!(Y=;O2FZFSbEb&nb&AO| zbbhz7JA~Eiwow#?LWo-y8cqF+(Paq?1Mn}SYe7PptOOXgV|AHS>f~R{fd`jUhoOmg zX?h-z1Wz>D2%&EdVO-Q-^9GEfoNA?SxKC!{(DoHw5arflmVR>A zX_ZsWA0AO`w+qUiq^7fSbc*%_F>WYt^s0y4K(cO&_TKhQV|d=}i&t3&q)v?)>f%|f zKU|yjq+iuqUAE;Tg6Dl^pl+9$l-iZ=IBaMa!#C;T!BYID|f z3p-4|XTPUYw!=^4kUB7K;t6T%BX97S=^9{zN56+tw$XnzSf#inyCSg_Q^!rr6N=3! zkgac_l=JG;;8yEcr`K}s!!-PsC|>%lNW?-7xrH^))?g6s_T=yiUn8XoWa(n@qiC+s z_%P(z!Ok9+0k+Oi3kqLtT91?R=6Kt>s@C8&Ux_?5@T3382KW&11EmB@Xm@Rftt>oC$5+NU!e4j^1aml3GtG$~SuD%#e zP?<-hwWbtbSVN0B6S^+*K+}`nbHTUVJh8tK_s1!fzD7%js6jqlMW+0lJo%~1F}rjr zQ~czYHteQsywdhUI-4o`+C!{9X?N)UZnU6?(^FIp!jk-bGXIyO;-8eQF4y(E2W?2% zQ=SsKj(9bF_Pq?AJa$AP#&ds<}fENA^xS2@cR;is5V>aF0a3e{0(UOkc^|O zofNd-G@es-bH1$y&?hpMV=U(%?h+WdE{OIUL?v0asK4uBvwXHNQT0&sb^>9Is-nBy3@?O2i?i*nHso;Do6Q8{OZ3wx?Ms?x!$4W1n znLw%TwVlw+FTx^rj!2rp)Ky6>E;06Cz=CW+X|-=_b<#oZi)z-d#LPzPFR%T)=QTP- zBC!U-C+R>TQs!Ws@*g3xA~|3h1HcR)M@mY{p&iLu%(`#+O&h|0vkS(rz0uxkL0`#* z!9@q%$4&KZ>A4V=HlK+|c7rWks2a_V3qam)N^{C=zFbW56NN75(;Du;4dqzNg7c>(xKrCr%DNnvvh{g)*vm)~-HSEn$CB&HxJ$xPR7Az0 zjaBR_(Z7BWtR5jx1+IggZw;d86%8|a0{LrBch;!EDI4_sC-1x)^fNNL|MIRNa#8mi z9YC(ffXH3f6ztBwc0zYLQNrp3=$gBI+Nx)Sf{|Ai%-6#Gj!~w4{g3U+)B$s8*%*fy@$|RNg^$s5m0UUP- zK}Mu_ra}p$7)hnQxPX*$d10NAV6ih$*{XBx_i0NWx1SuG5bjPBMQ$&Nc$!%R%insI z_gpr?xHgR1a>}SU{?)aRX2}0j0RxlI`EZ(oaM{UOya4poG%_tB4t5 z*8i$AxQWJk7rUP21s?&pxfO6Y8z7|atNE|ma%LA4qdkSz8Cl-uZVrtk=_Zg1B&#=U-5&!3~#H=;`=dehcLjLEl!q#em z!;004s!zRe=U1Z=QU(!HkV0(1-~u%8Y^Hd&Vu)=4?Hm}YFnyp=aLiP(bVePPsTP@e z2wMW5M;jwxuoRH=OfUF{rqj{sXAxk1t^o|c#T4qxuK}x|B1R{pdpo37{R@lghifGe z80tqJ!BI~u4&#f~f9(<~5Mz`OJ*XJ;E@MYOm;b8l2kU1B8VN>UxkdiVNB|K|Pi9Bi zX-`9oS`1_&-^@&}Yu zLYDpIny6~1Xj%`!Mq0P8a(A0OQEL=JTAxR%{F9TPYTO!Bk2NV@WnCf=Lp4H%hm16Nt^l6##|MXF~#HL^>%0A0_ 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 NtC^D}n0$Vi{{iyTIz#{f literal 0 HcmV?d00001 diff --git a/assets/rancher-logging/rancher-logging-104.1.1+up4.8.0.tgz b/assets/rancher-logging/rancher-logging-104.1.1+up4.8.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..15cf0e1f707ed584d31210f1cd5afa908761c233 GIT binary patch literal 19602 zcmV)(K#RX0iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PMZ{avL|&DE|Gsd()}Q*XteZ?ZLmjUa$P`pud0cU;VvS!*y6%dFkYrX{ zDJ6VHrGOs9G|4_ZTGo%0vpJ23=uGB(hz$5(gp+?`8pbS(0?L9g&V(d<9J8zLygwom z_iKUKK`Hch5d6(_b`bP?&7I{WCRh+d(bD+V){u)-QAQ)zk&MN)#WLCn*(_xVNu=vy zeaTcvPVg-6z+Uie&}-q8{$#(*2Q8eYKNSl^M1-8C5V%XKw$BxT{%4s$VC~MJBH8rL&8Fsr^ z2qHx{W)mj5CCUY2K51Q&#TDa`7`8f&039^e?YqB5RJK%eKY7Dv=ju1D`f(8~;~@dS z7Gr~C$YurPyLRqcx~x%UO5#~3R6Bv_N=`_3hH26@A1d(le86cM(-1gG%Z+2dw-@w- z{$I0H57_7CcH2}=<^6w-6B^goBMUv3` zv|t%WlFZT=OCo|+ixc1)M=VpDM8DOdGdv+m65%9ef=b30j{9|Ilyk;O)bY7hr^1jB zl6YeG2!zrsj*nSP!^IH29KT`mm=i$~*=mtwK1A<-Y0X)j&4}>+eytGFA6n#tF&>dv1i<~@&I#uwBuP-p6p6Fhi10v7 z2*%|QecSuC*RrKg37^xDph)$ED%_w4zh#6kV7o*@mr(W1pQQcX`7O;0|;p`*hQPzgUk)gUsNl3?wO1&9QG91SXT}Wph>by4~u7of^t=5bsY6;V1GR*1rT7Mjx zuH`slbj;a|$SKK$8*@7}rWRtOUr8tfsO(TS69DKJMKFFiewC9%Wz2}=G&~_dDVj|5 z+Eh8b^i5C5V-}%P5@wvr#Su#+`5<9Vl;z9-y?@QPTG(Uu%L8A2)Pg6dEi4q>kR>5W zrRb)>jJm=A?}Qq9cek~(Q)zO_;z+2K(}~HP#K_h{SV~SunG$W)IEHLCV+m5QFii+Y zf=H>l6ey^`y(7)(VHzbYL7XwE)*44wR8CPwBh>HpdH`-hBQ)ssdcj{F&ilbJi%NL? zMU#AI2XQhkip`~NODry-^J6;6IO(XaI4r9~Xr-05Upbo{RSn#>qqxSa}d@>@oPQZ=YjsatLfGi!MV{Y+3MfCV8= z)XXPIgc2rUM>I^!%=UZ(gn2C)iV2<*B-M(*N}dT>B0|bCp-DPriq+Y@Pc4r?FCQEW zhG?R;AVGxMxRX%-%cW4$P$`!rnN!Y^8A+tj%POWy&jr{Hl}AWq;Z!yMnkH0Ds{p+m zEAa?L3|--*&=ap(mgwF}z0)%_hqPL~gJPPfA~^ar6Ocbs4J0HaLSVjlq}e^0G3Y%( zVaDSH8gUG?8B4;^H#w=l2@Fs*1a@wPX$GroW`56L9hH@EaY@scy6{QPFN(me=!zyJQPYW7JOfX?;rOc5 zTOpMMqgeuHnbK{hjH%5Pr5R6|&;nH6!=i|68h;VviRzY_4BiNZY?j7E5)i1|=Q4#H z7?t1A^*k)a3e%O_uJS6~kVnE=7Q3$Db0yM>u8)ge5KB7})pa9U+KK2+dJvWIkKDE~ z=>0%ZO1J>EKq4U-SIdRw3tK6)jJrPN3s$qk9|?!zI6>qCR{edXxc-z~DT+AFiJA=) zjk58W@KfE+PoP>_&WO@^=>A5)?7g2z3EM=7*NSNszAGK{gy86BP9=Gpgv8Ix`FF8O znJv3yNH9cuy&q_<4lP8?CY?7w_*|kmT58EbsW(3qW`{K=sMP?Z%n~>tAdzA*!mKn{ zz9pW*Vzm#beKv-oNKUat5si}n_kaGcQaYsCGLr>jz#$X}H7I6$)XxGUKg4W=g$AQHF}rD~JvLXsp^Ym5<+z^dhSsZmogV3uZ(QX&gIwIEt>&h= zF^bp>)5MW^M6?cnH6@9)_b7Jx?&KBVV1!FJ8_^J+0e~TDo8LjqLL3MAFgQG5Qkhcd zO0BlyJj%D;m|l{?e&OvOy4z+piYd$DNMVgp%9$jg+8T0;$e06ZCRvO*NQ5FlC&gxR zZmt@!?Bj~YF-V3q(E?`<6AN@j;#kpHsS2FMZ}MX&Z~7g^)uqD5jsSUY0ZBCrT^j*< zok=YvlMku_of9pS9+g^DV3c-jp&yl@w~W4GGF<0ha5g)PV}JS;w_GK39ZnRpJt}dJ z#OCB;J?bER+;K&d4pw=NS8@i2F5clFe0Mh3}dV{}GXCOi6MuSP;`kSHQD z*RsUb6id-b$W?cz0IO4g)zPr@LbX^GxZrc>#0k;X$)6d&jG5BhU(RNkR9P=5iKC+_ zPA0_kSSungLL{dFdu@(nanuZRX;;4pdBO3 zfG#_Mf;d6cVvWWMZM_Wx$SW!ox6NX+C69%>jN>cH-K_hU0jN00+`Q zMRXIejpi&*r->)5C}nPl-nRjX_Afpf7JF0G;*q0UhX~{r@fdM-2~r5;b*2PIF%cqw zpMjW%L17yn4*u5r+n@kJpZ}EEpEid7DuBV~8Ae1qmn@~>5Wzp1`p=aNc7|z8xLI9l z&g375b#~sITSCc>gre}-9UmcUTh7ms)W+t4)@4mm@3hIUEb(MnEr}Y z+w(W2J?A#hI#5f1IIX7t1HBd&reJOp%?~TC3=exvB({pafb80wnws^s>S{PaqgbW- z87xp!CJM_&pM$xNO-l)if#lA{<>GpoDZtxB<`!A=G^nBA#*<ap57m6zO9h;*qALldt;at#vd#$>xaGE8T zl}vF-)AN`mlXI|V`&pde=v=8e=W4^MHd(hU@?3A$dXy>-YEDeecB1Ri6Y6#}#nvL0 zX-yjkhDb@PF_D3Pz^e<+@Q3G#s18R;LMXTX^N9e5#SmA zH%su9053((V$#7p8KS?Ru$Ua4yfIKth{$4zItWJ*iR{Tq`838gqD5qA#M+2kR*Wy5 zd*9Tkg9mhpr5o?*UnmST02ISMG+ZgVC2sP@oW;B5g5xX7=#e{K*AOjck0`Y zJ2mob?Z(Fn){Wi(M9VP5<9TSkPIk;ODEIt0@&hn;2nUv8t*wFC%P=*Mf2-lQUt>0b z-3%#(w`IP*Vv}Ro;o4oEC9uW)$}*ndxZP@Lb<8-#%ecTgje+}wOsJ5GQMB7;8NMqV z&W?y8kGx{~U{(>6P*BW`P|mnJLit%+wVWfkq5{|pwRad5rUm1NPa-s@7+SFd|L)}@ zM5Q)33LntybpWx%eKH`$Bh!S&ju_+&l^ANnHKmR@8Pg9#)DDOL z`WNI2@`@(ehgxM;yA0~f7chIzIZ?8n72=orLHNiv}c8KSn~o9z`) z@nsWK(wH-8q>mbd!z{AY!RpT!G$vZmHk`Kx|I}ZH?M6bMsgZ7+4Eh%<)(hZ`E^>%Nll7z}`K*s1Y8S+5Nu!)R^L&p(hbldz$> zJy8H?1WOjNGSPD4P)rCs5F;vl|jo}@^$C&T8@tCoFqhuW6nla zcn{N4#q`~b(F)CAZ?LCTFVF>W{EWnSaY{m#L}G{@>%5e33Z9JmYk%Kx%)&9Me_*eF z7aX17i*-_m3HwSjhL69u3e%Y;X$H!v#`Js5CXPVCK2-{~T?8iQHU3ci{+i6rzt6_! zuMB4~U$alvrB(&uB$!DH3A&_DkmIYu*_(6Q1_^P>y!QA`l# z953`$gx9u^nHD=r?eVY5^^GojNt0-3&Rt*Q)Op}pJ;vzKS~qn1ud%GFmO2(6>ssnn zL#7CPLv5fbbmrMx^ycjuI(>eI&VGD(ir&3>_5Ab{{mP-9jX1%Vc9+ftO^!mWl$0zXA5wjAKO$2+r%Xw) zN_Ivxkt8u{q4iAA(rjx7B}8Xh>fv~Lo z|l5s1Uv51Zrn%_Bk1d7f+eL(CV5j0bi%N)jO zju_`0Q6IrUFLK=?K!?e~QXM3IrCrg;I0~2yP_pEdw01mBKVslcpj$SsPZ3GhgQ&Cs zdoD?1q6P_FxSK)tlA*YO23k9+2|7uXTo!C^5#C}d-~Y>p;LY2!=cj@EAaC5piu?cY zck%w;{*%Z1+xvg_k($T<9Gqlnm}_?+8eZdS=!)?_*y|69<3AYm_8)J@|31>kj~#8* zCa7Jx_E{QvnZ|9@`Th68#r*o%1ukBJmO-445vUX`Uj*@jEqwflf)gE%AjnS_S!7{rV~8*78yESeXAz0($O(1L0r&W%I@=#7ba1)IOo# zGA7COQLLT1HI|kYD3-yjiDLaW@E~MKh$VVpTl6eCyZP4~4?llb11s9IZm<{mwliI% zWKFx3eJ*#W|GjLTTNl3lQwd6~rQ%g4X&ivcUXrx5l=bmr_aQoCDKb}y!Kw+Y`&5#MZ>3POu3LKu$XlpBALdBYFA_@yf~KtbBLb1B7<-5 zj3oNN+lQaV0H3oN5a@xG(H$9U1y zqB)*NA3xeIQk?OsEz5|9-z$*8h8Z2iy3M_mY;bPdoD0SNv^+#?PejS8vuWX|doL&>$m3fjxw? za+G%{_c1pKlmx(n$8@9ZL7%Xn+uIV{co=C@fhYKBj}eEF=X`CN%S{puRU~%Ov_AJZ zF+L|R?*h@1U&|&4m#cb+H;z!Ft>RkNipp5}PHP^*Wur}l)DOcI(-1omUxYX|0g?>S zA-hJ@uhuQ0=G!|;W{ZO1U{mwQItGw6O(3snft$@`+z zD|zZrMY&qb)F)pK-0DsLQE7?(HzjdOxKN{h zvo@CNfBpU5-jmY#|G~lDldb-DA4zjwIvavV&X~qTE>iMzrpOXb$^^L{aH6)2aTdo5^jn5wc#QzzG=(k%t)Gd84&|k4Lv=@>5z$^{g3X8@L|(_~)#8EL zBES>dUO1uxJpkt_f}XuORb^pIO-Z;Lv|f&p3AL|*7!PaV2LPtICl@%WL3lzJ&UYOe z+YrCrF5qb(rTD+DOk;tyXdjCl(pS)r;nVep*Td71L_;a)={c^2uNxzna+=67YJV*{ zUyF7Lnr?TK3D@-Z(iLOo!8+q*#`>$=(K5t)# z&FYB5+6K1SW9iGs z`K)#gnknaOnZu_JiBCupo?yN(W|(%<1sz?!ZLa0)t}5=6Ag^RLYP$p~h^_9Py>M7G z&VI5Mo5tbIZxMnPr7xVPdR@5zUOuX>?YdR&v6^KgSsEKhiM9*mk|WyQgdF*eO60Tj zHPITZz>ALT16o~Gx+@5u6Tny829~B#PJYWMClPA9E8NIqe?~m_MlxplMJq&wt9(;@ z8nuPGSp@Rprqjn>kiEUh0~mE;HVJ+eEZK+xg)6(aJ9Pkb5VOfGAyk{lJDH-$Td!d)brW6D`3JV&XNMZ%f*_4TiH1a$*gPoMY4hbO1c zPjrwZ5Q_`xGG-IVdI13e{VYx<i+SjwMBlPuIYZYPg2QN3K zjY8pRyFiiPue)so1bgZz7yNY>&BO#s&cp=De0AMky*T^&$KltnhhLwr>X^GoTkVwz z{CGnIg0EjK;f_W=QtQv&Vb_5?7GRLe>9*O4oV|Y_irPzI+ilaCdt*Dhw1^ zyTTc#v-L~s3&qfrf}&B&QuK8k^gWdb96nHftp%-NV{E(;Q?uRZKthJI-q6*>#RDmM zkdztt&6}xfU~OWa;mO8Sgd0Jt$hU$h#y6&7v})?3Uw-Y*ZQ8MRbx=0EVl}+p&8jK~ z(fmdfLLiyA^$^P-uO>cFGhHDQnoES1&JGHyJ+nG1WHRQEEQ_HIoBW@0&dbyW;$}fAD0#bpHEf ze}8-adoQWPJopHQzR|MN=@guPAs=UQ$~gVEe%tBtTW$NcF2DAP2o{ry+waP2vhMg2 zcsS2u{l+y;DZJ=so?tD7n}KgG{+VbYG$(vyzk}KXe?}xG=FbU{@UK#-;E&WiV&5^b z>)}s$0OcCZcaYE_gFg!@B#BZ+6R9!DAAiw5S>*rKO*#9pD56q@(QEXK?#vpj9=1Z(%2eJCY*>0;&(vA5^nlk+!}VyB70o{ ziqP9cEfY&ov~ov|YUvhJ!)WO@5bmCYH^i^27HrlqwJLbrM(gUvi@y&KnHp|5orl{(j&4>SE>pz2e|IAQQ+LXFtqULgeIfJQ_s zSq8%0(|(Ca6H&o4IF=e^(d0hlv?liGw@A=L1Yjl*(^Yf zWbrX0eYN^Jh?S#REO%Zv7ZkK@o5kdWj1^Lr&nzKt%SH3{tn1gpxe%;s>H6o9xZ%N% zNvqcXU@$1(|LZ^A#(%k&R6ab0?db>{%pPQj?$^}-&f7;(GpZ`8S*q;C1 zOY%2&oTeh*$Dg_Juiw9$x4OzMdEGtomZCt_hSV`1kKnmO6D`=pRe^mSUhjV8-o{Yr zrkB>5pe(y?k2)v@EWS_wu4g zTmL!6ys6r#GT-{33sIEJw5h~NN;zc^OUb?p?ZrnbXBFmJW5rdStUOoj8mv4{yis?( zHodpL3NLxPN#oxlEexS~6t;bRkISN)<*<@1@x%+`Qg;cn?coEj%NC}X6n>oG?LJG}*+B9u zboFz~y4zGu&H7*Q1-P4-f>zmo`u$!x{_o@7-d6v+kM!|los8t37|cyI5b^GTWoo$Y*1c{StiZ-UND!7#*fqQ!8SGN*^{Ht2yQ!ZZ@&{mmw z`9ae)ynEoQYp;Lf<#8PjuyXzHm*fBUpB(hI>;FE|b=JS03QIV^TRm59$^$f*3tcKjo-!gbgzF;vH`QxD| z5dPz$MPq1WisZlR&8r4P&AEwdt8{SEXh_X}K;&ZeCmkb8J-A0-TL=(QRQHN#3@f&VtO&2+QknSS>u$^&hFFIa9g7$ zLzY5J@S>m0 z@`}EnOo7pxAt;g8N>~0KQ7V$d85BYf4C2@2##mS^Wq1^;RlQ#07q4?ZTIsdcnQmgs@ji3Kr#s42a zsht1y1_xXIe=ljZ{r}e9{Jp+ddo%a%#x1U_V&uPlBUA&wsb~u9>Igyv98F1hX|*D= z0o7-2-io-S=}Y}o#Yyqa&bpkN^uoP^Q|f^Iz7#ecFH;($TxBenKs3ktATHMzd1i1J9<_9MNz^}&FOP6n3CD=wseG#)OUDEq-J1r2-nK@Z=6TkRv z^J$}>7SVB)&3r6;x*g2n`m;06TM?r8@h(~_I}tVtvviJX0<$^;ZuKei z_0Km}A8(Xk;aDwtbKTUkloy=M4&%5y3hR~Kd}1XmB48si?c~32X)$apK5s0tZ`9u~ z-z40q+YcM`cmoM`rTizl_)>I>ad$S91y||+y?(zW{|)w^>~H12`$!+x3gxXw9bbB} z^1q7N_B8+~aL)EL-eu)E0D^5 z9P7Myf-ehihJ9T6jB{~#+UNm15K{MmbIm}O&DfuNB5u=XNo(@|8yNvs`TsqBQs)2t z!C>qEcQ0uv|97IGW&Gz~}c{P(0R{~h$U{(tw9 zHj)3xYWdH+ueA}oAb%Knk1Un!|Sk44u#Z+Hjy{~r(f75#5-f2;r9ORBm5)3`n_ALmNR z1M=H?72L(cbCOJe%^0WYHn@NJ-i3Jxd6;dlak?hMxqK{c>MUp*(R*fRL?t+54ACdp z>ffI}Kl$n9(eq!NzV{-|#MHkui~26_2adzytNHsb?-{%{=;ys1k6rF7HaUMq<|KBx zG#N9OeZ)9BKb1JVJU^xXR!t1{_MaTMd~JRd=Pzh%+E4Wt=!_24_x|OZ<9BCyN2)LU zn*nkq&hVsI0BM5THf50xzGIRB^{OmsA#|#9&b4T#zMP-_&*|Co*U!%1y?J@|RLvcu z^EZW#TsrTB_A=G2y$c*zOz~jKDKbIwJDzWP46$5Ebo|*cp?U&tL<>?X` zc1ulbLh4D>45V4)&u<{)R$?=(?ION;YbL*xSFz4Ebx8GMhQldMNQXwXEi`7=Hc~l0 zTp0;`^N8lxi=cj;cIu*fUuW6daP^f{SD7rK)#r=Ta5=|mSKwBs#gqv>=mogxEltVJ zvdOZn>GBLL--dU4T|fHjY5 z1|78do6qJ_aI~i9>Aj~sk$GnRn)GRY8gWB1UGEve!ux@nwYbr9ikpEh(^8Lf>3Z>T z{y>F(XXW1IL%8jB%;}uQWI~>c5Xa_JacorMvCt!-=T;VzAv(#DLvfhsXM^<~bHbQ} zr}2P2xgCeAlJ5lJ4b_dP(3G2{X-sA$kvR5OO{Jj6zB@UGhF@fs%EdFv&Fjh`H_y{r zp7*DXmhhjK*3|#+)c>Quw_ox97;OE&?d*(!p6on`>R^_|gcCQ*ZRPdG9byo`>_^V)vA5G>#$dV9C^q|H}y_tWg@{#Fc1Q;a$h)H1E^hJ79b3=Zg`MH{<`;a|2%` z{~a7WuIT^0t^fDEr1j*#+hY8iugX<18m|xOhBx%C!8kS%GVhC3tg-(2CAm}o@BYD) z%KLBod)xS5_mb9~?!0(6<5t|Z`6an`x9zHf^*UTc^}Zm@oyP#fJ1oAA>vh$!T9ZVl zs=uhjG%omEpZ}9A@@!{pEaK!th*)^(xyC;GzSKVIsx~^&NdKGr)<7&b5=5iiS(VJr zzt6^=Yv|^boRQi2C>xInKaT-SfuLo-a&2Cwqpo3Ez?ot;={{6L@~7~+z4dKiP5ytU z{-1k~%l5zi_WtiZrEBtkIQq%C0~$U>;E*^*?XSV*&}4MIcX!%u{c0}ME<2#;&nJw@ zXOx4Ix43N|QGQ82muqOT>6IR#8+8KRnHOdS>o39ia$V2Hrv0MUC6Fc&5HFDX_v(ammbDx7pf>V;y-+u=@(4H+9qGHWb1JUZwTi3pNzVB#zI0=i1>@ zbR(l?)w#B&kw1_J?=5?hUUxhEf*eT8UAT3>(YpEirMrt(h;mn6qUDBe?i^Z%c(*>G zHo3p zWyD2yd1}-|%`f5n=nFs8K!4)k9qm;Dal5urBPCz6(QU+#TZ$O6ird^}$Pm@`mlHFj zIw6;}yTPpgQiGD*d>8++4wV`@a~H=;OP0(Z;Gn6AP*F@>*)WCUH9gvPAl~P!Q(;Y{&%mx_5Zw=w8{NXH4(hXA5M3Bm4^ViJ15X} zIjO?2>Aq2O6Iz68a`!77f~*yMq`oSui$c;|w4zxQ1as532hQ-w$!{6uL?5l>cWc`y zFn&1x#R*kZ84Q${NL>VI;eq~dv45(Yf z?2OY{6*cws8n_u?w}PB8?H5pUZR zs1^JF{@y_~{`ceU{l9xjYu*3NH~yRK!ud{hMU#kKiRW6M&o`)qMdVN|X1Ay6Hm+!* zodV3pm~u9zvCdF{JUbUue_=U8ZU>3%sf2GD@h#Ch6>a^?N}>kqb)GubT3s+!YlZ6E z$V2CxOsJ52p^elY=Y_i3q6b|+&si}i;Owo%mf?DJWFCH^oP2A0$2YgjxX>?SekoYV z@(~MUoQLemt!1EfHtbUCUN)+o3Z49_*FY3kJ;c&v}|Yy6=ZVVk)wx(?WFBU`*4Tc};gT8U^8(5<7H#gfJ} zA?MmJu83$cb2X|ZU>>rc&~F)&oU(tk=uFRA&S0Y^ob`7K(R6?C{ z#jtjHzqE)z&GnafIj+&|!frS@`<%OI`^(uz%V&@}-S0kHr)AynxpgJAq0jT&y5BUq z$$RUajg-v|BC`C4s+Z0BpP2#Id-AuCR>gnm?U&yF?H?RG-unOFOImgUT<^ud#B`Iz zaUoQlcXYM1qATZW-snnz-Db4o%~6~QN%+fSKUALMOj9XS>uMf^wx~wJ{nV_whTW!& zOYdlw7o|CXt-g95ADB;wJcg1gJJ(<&3t2owXGg~^e>*XSik@vaO(8;*vBXiuK*>2LM@|G~jQdHwhHx9k62l9vD6Ed?Uvi5+sw z20BgG{jX^z;99fHmw!h!+p$ya2F##Y@n5c}7rNc7uzMITSK7UTx1hMMrq|}$e3`G8 zuJDmGW{VkVV(g!DY**g#yE7VZPUTg12g?`g?hy6sAm3=;_m0t6mwW)shNvxhX2QYc z2R)Sy77kaAvp7Bl-)-;kuAEamPgr(ksd6N@>{_Af>(LZ*S?Vb&UN5ZW4Uk_t0K$Ay zINnjnaGXp?JqT62?1|Cw?28TO8zmCy>jg`gm@88RP`Xc2N8mbeu9`>v{-6ljW3gqD zSLR}Al#bV8$X~V~^#@JO@?Rzh=PbU31E5v*zdTh>ZuY*Dx$+d$b5|hH8A&ZrqL*a#|4w{%-PB9hI2J;K2 z@K=^b7RnWTyf(UGA!0U3COO*n%YCB1W%Ku$R`Y*x;|*XH|9^bYEA#)sVC(;VFX>j9 zyJP6Ue%rUfx|{D?!;R{C)>eCW+Goi6SI*T6_oo5y!|Ija+au4MlB-*x&IT1#o42(g z-uY<2_M&N7EMz_|8M%oIy5P1O{X_3ApL@N1X{nk2&v8uE*4zOzK^%8N9$jxMSZV)# zT#5fR=xycydr3P+0hmbiASMZV5Hog}rKr7(+qF^K<8*D*R{!npq8`|acXTlSG0Tz& z4WFWjhSJLrMA}Tp5XlEg676eH_H=8g5* zz8NYv8g7lrDJW`hez^Hetc7=*7~XsmSWvgt%ckxbGj5Y#lvk3D(G-h+l7(&hfxAQ! z?3!|aDPdPAqU0+No^@ZZ`=zn^>iiMmr%gbRpJ`^5fr zbn;9f%n6!NAr#%vF`Nk?BLW~fB`9Q^6Ol5A6Qru3aEiG^BQj>(6;*k1N`=l0V2@bY zJ@3co-WUHYX?^+c`euMt{y%$r75|^Ty{-S}y`-IuLZsNzjH3rrEKalWn0`QQFV@R? z@mva(*A4-*Q)F99P@QE$qJ&A{CUE>HptT|Tru&V;{u>YFZ*u13*&cWP9CpYx)_*F} zoAH2E>;Irv)&CxE^}l;bccK4n63EdOR*Q9&2YNB)Ubhl$ubp#=F{UwUpG}Ez;IW1y z6fq*8u_>MtkY_4j(Bbh*XRdN0P(+178Xcb=3q%u7xUrH?%2`N=l8S=m?Bq*gE#>te zOi4VWlZ0_{Yi+Dr|N94}`yc(iz5Rpj`oE8~gO0J3geL+?hV;Ort0_s)D5Eim_$dxA z;X-t42c4-|FR~PzJ&>4^I7VuHYey`aOdf&1yrgpiw*tKHIEh+2C?OMICg?#5F)fJM zpZ|L|KyQ29K|#tK`VH6dVVSyC#@ZH#AY*=pr4LTQAD|D1rsW}@PCbd zD;WKocj5o`!*tSB|Fb{EJn80uMmSU)Z%kt%S`Pzpm9`!RBYfF<7|5CWn{hg6J^cS# zJLo6ODa!ZFSa!s38Rldc{rCIJ zY(&u99yxxL9f$W(Uhw8^`K`ec3izqZ*`;Z|NA}Wl8$jG(KH*aXvr4+deEC@ zBfCO6j!-Mx%i&v4(`=;RTaMaQn=SOnt-tbU?6z9QQi<#*G-e#-;fK%&3lbrgAY*2Q z+kDP?8?;&vAO6T@B*haleE1Ok-6G|;tGK5|?z>iNX9u0V`d`mZ{#UDYad9!iV%k!O zIxA48Ga-q>g>(`;BdF84!c-y_(qXqdnTA~TvCu13y#vCMsPs^^(P}Xc`;Tb>wge1r zq;yO}H%;yZA=K%Z_Rv>9JwG{p`Sy**ac2j;OeAMfrafC)XPykmm=u!ZR3MDr+aY^v zK;|>S&^ctQ#vMh@30sXVM(^_>*Wk<$I)C0>C*)>Ao8Jg}|09WKdF!g%ftc>vJsr(( zf+vIr(79tyK)V)H647dP{7Kdi`hWYYA%QdS9i2QAt=2n1(1mseI?9A(vlAmbKLw-X zg&s|X2%0}uqm1W_Mo97nV9AUlk+wdLIhz6I7a@{mt zFvS#g0uL35Cq*0pJUobkR34iX&S^w|n<#)b(#%{@5IxY-8mFnz!FGM%o_lejjhEv$ zOdfM0NFt%V_qsvATB~pQWGp(PM=XSx!68XyA$YKk#?##aM=?b&{b3gnw;vIXIl<8a zfw^0K(53X!NmxWQ`Xrg7Pv94z@O}S_8$T0qd|9Rr?Nna^B0wGTiFn`prAU&FR(3lv zJp9rj#x3qCI8+p;kM9*<+lpdtZ|%5M2lo&PDCIPbapkO z?Q%72$&koKLQlw`9J@#~qZhsCb7z5cX^AAf(;c2P;%!}c4NkoKdtx!nlaN)&4k z+wSsH8;E1BYUxm)aK#*m^IJyv0$R5LpEN!NH{hHiYR)QXN19=)Qnns4_k@8{Yqvpw zv^pd}4Z#h3jE*^*5jiE9aD*-e1u(Q))mY_XeRckE`)iO>xsv{1^Dg|J4#LA&La=pCo0fO1XDT6j+ zECfgqRSex4suT`P9~&<}U!UI=Z;BiK;@u~zkn#9k_cfU*dB+xmLmwiPtWIZC?T%_+ z@!z^?SkC^dTje$PhD8LO`32M#GY0;+r~wG&4_&@qu#McrQ0Hn&!zol1*4V61*hM%c zQ5J*ZrfFgbS7!fl%&x4l-BRrZXS2gNb}zt)_7JAN+Z>*;8Ky~lXnzMW3vnE@U4a)d zyAti;`(NA_?E_)IF{S6^4YY^t_M^60tKfD4dyQt{Cq!?gKQn$AGaS85Ue0EjR9P>S zN_{lN$%Hr*4d2gybIwfbCuFQ!BA&Asv@}*!fc1JbCE?{WZH&)> z@H&)dfS%)UYGu|Ol0YF&jGl^ce)SXq9t`30xff|+Z?HKL5)w-?&SF7ivAYd(s8-@L zhdl-2=~q4NX%9}*7!=rqT)DQF5W8;R>ze*~sstXehNvot>N-fRI_RnA;^p(v+Kw&} zxm}huomlJxy)jdPFyi>CL<0i`WOL54QB1^?G0?cujHgUk!7oRqwB+hK{UXL-39yH3 z`6!2Mmc~Sqcu^0vhV{O15m<}33$)zw<+j_rN;l+@a0iaA(Q_qai*5}@(dNC3miIAg z>|t~#-HYlvXBkrsF4~8#^X3PC;gu$h56as_>bFfD?p9@kf}g+%5{VQ5Vdf@OF0D;{ z;Y=VL$50f>DV8XrQS$%(&;OPB917uNffy_=1){_a3;R&biunP!zb@gl;V}fdetvTD z_5{JM1(K`}x3Fncq!10%#G{A0z*rDVbT2HoNfxFHjGMw}M#3phsF)S|QQ8_RE$TSp zNnSuQeK#U!F{Y0pXvSrIzP_C$lGtrESdeXs<5LoIK#X(;{!rYG*NA8p9*#JTF;PKz zck&7lGa_)2p_av=n#qypsab0cu~&-07AI=XvSWHl3f$b|?wTNGx{E2x;z*&6A?OGR z6}QeUCSVxlWRk_0gYF~(bW&_4=a*nfHT>g>#xdeq;`|wMm{_1I634|6SWg(OV||Bl zb;+`^qf<^4=!=@|4wV4C&SZw;c!40)grIYxmBXX*uyCS=CA83wD$xDT`g90n+yaBL2(;atN2^>VKPd!>oLQedM-()lurtuAU8ugftukS5fcTYRsIQ5{R#g*qZ8Q{I0d_5rtHC*==~8%gr96PS z31u07%J1qmRjx8BmFcmm#GI|J26fwfs{;BaY^wt7_PACB^c^rQuZlD(#h< zV9QGHmr4s6v8;)Zxq(8TM+IS;mBfo)Z?B;qQ!b1Hm1JpGD9FVaH+^H&#w0Xflb3XXF*H-IPVy+!5lS=j@^xpSRLLjG5BG&V7v5qa>ltmrq zEcJ+n55g`fUWX9$s%6)}BJPwav2Cdd199|LuZ2aLvbBK~H>)OMIuu*`&=$I2R zb(;(fUWF2NICmeJIj5!w`H*VkyksaPT#X=D7n6?m$kZ4Z&rG+aUDUX#3lpb?Te ziIR>Hm1v5ECP&K2oU%;B3s(@#K0&MX9eVii4U=T}@L}sa^s;bk(Zr2@1lD#7!#96k zsoh%$7E(AJ){7-spyShH&!k=*7Mh?jo-108^Ep1T=UgO?hRZrz#d-|O%93uOCc0fp zbyL(HnE^U#u;Iq0k}5E|fNKK=)CGE=G*v}T)xZoV`jjDz2~JR!=AGPClZZ-vUJ?^~ za}-?K4H@+;8F6+=5^bdhg3+RMA+m6)i960X7_0$?W@>PT3r!?Uf=Y@W7=#lu7cU-_ zy6^}Q83wz7qLiZ**CQ;@gh(W07GAmo9>DAoN;S?QOVknp6zw*k)}+U995DcHp~pgN z{6VYrE@g=mik3}e$+TYf$a75AhfpwgYNnUo0rdSAD%Fgi;&_}deS7lfoECgnc8iks zBzD0_9DjgC2{$ZM2{lj39PBWHP$>QdsLfdzwm`bO-dSEINaSu8H;%;E?gtT(n8t;n zaXVZ-=5BCG$E|8I!2(tdB;*R!_foskzyWljz^TMZgn1hjQeLUuIGCn?0XIS zoMoBj@CQQt*`pree#6$CB#xn)pnu3aUp1dJR^~KhJ)9Cm5=pt6KqZuH137B-O~M73 z4tj5o8ehch>bmkz!5PDgerOyrc2Nf%77)|tSVt$%(1Q!_FzI5~_&$IOqCi*bhjxj` zN#Pbykqk!o@*9Cz8Y7agM8nhI;!WYe*mvr3ZmvFc^g-2a(npU*EroPe4UIGwWh&*1 zO3gU+r;``;=`9yXfaBT%G(x2|NJ~yt%=)L0G6pv!pa#j3IY}tE&#|$&;Du}Y3Vk9J z_7+?mNM`;8>`4;2IU%P^5U-nxQLs#+L`O5wDmA#Xx(j)BEz$%L98P^_1jh9z)fSBY zt*wd5Vkj?y&1Zj(H&miPLvNs<1GhMBtMfIfnW#6Kq0m=jvk-9Fq}?rTq18%8zOgtd z2R0W^+i)4?zBq8hQ*CH1x=gfA*{mR;M^xxL0wC|i4CdFbEaM4|qW~!>mGMY7W5-MH z3&yRBpbKNteZ?lnSWYisrV8WUqsbKo=;tYobr&wWJOgc~YudR$k&6{X^GiL>@*@<^ zuV|8eD4`oM5YDWC0hFKutn>j=WHnZ5^lp?TGAmqfxNuf{i$#FYnOa+t@R?d(u#Z5b{)mkXrWJN!byrc&(Z(>*Umpq-HB(INz{qjPur+79$X+8X5b*u zRKg;q;wrK6A|+hF?Id}jNWzKCctWBEoN_UywpR+^oW)qum=wV+2UQ-X03hK^vLY1i ziA%>dt?L_r0^&^=O$khga!L|VpQ}|Kd7d7+L*W}vQ*GSSb3lZgj!1;8Pl-kE zQQ4-FOZ6jy;2_?c+s3&Jr7=#3-9;F}QN)Q5dVWzMG6LG&g&EtY9(fal3bR42(-C7* zkKGK1Q<@M>5CBmg0hpWBE`M&*)HdBiD%*cyev3{XL>JiE&7J^Q5&x&(FUSAtKiS{! zZSBAJk^F1FL%VymT03Y$=OjT_h9lM%151>Dx}=z(Jtny#xu6LbOwH@Sirbjz1qMv< zy|UrAy>ELhALHaF<^%a}62SD+GE?r3<02VXoj9ik%5cNgf_wy@EC1if?`MXWqv`yQzP1j5Re*gdg N|No+firoP40RZK}j$i-) literal 0 HcmV?d00001 diff --git a/assets/rancher-monitoring-crd/rancher-monitoring-crd-104.1.1+up57.0.3.tgz b/assets/rancher-monitoring-crd/rancher-monitoring-crd-104.1.1+up57.0.3.tgz new file mode 100644 index 0000000000000000000000000000000000000000..85ed3dda990b05131325e4e678a7e3056cd2810c GIT binary patch literal 310389 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 z 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 xuQ69&hqDc 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