From 3713836465e46d2656db7f470425f8e6e702ab1f Mon Sep 17 00:00:00 2001 From: Nicholas openSUSE Software Engineer Date: Mon, 21 Oct 2024 17:03:50 -0300 Subject: [PATCH] [release-v2.9] 2nd batch release 2.9.3 (#4607) --- .../rancher-logging-crd-104.1.2+up4.8.0.tgz | Bin 0 -> 170045 bytes .../rancher-logging-104.1.2+up4.8.0.tgz | Bin 0 -> 19595 bytes ...ancher-monitoring-crd-104.1.2+up57.0.3.tgz | Bin 0 -> 310450 bytes .../rancher-monitoring-104.1.2+up57.0.3.tgz | Bin 0 -> 480734 bytes .../104.1.2+up4.8.0/Chart.yaml | 10 + .../104.1.2+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.2+up4.8.0/.helmignore | 26 + .../104.1.2+up4.8.0/Chart.yaml | 30 + .../rancher-logging/104.1.2+up4.8.0/README.md | 134 + .../104.1.2+up4.8.0/app-readme.md | 45 + .../104.1.2+up4.8.0/templates/NOTES.txt | 0 .../templates/_generic_fluentbitagent.yaml | 82 + .../templates/_generic_logging.yaml | 72 + .../104.1.2+up4.8.0/templates/_helpers.tpl | 197 + .../templates/clusterrole.yaml | 388 + .../templates/clusterrolebinding.yaml | 18 + .../104.1.2+up4.8.0/templates/crds.yaml | 6 + .../104.1.2+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.2+up4.8.0/templates/service.yaml | 20 + .../templates/service_monitor.yaml | 30 + .../templates/serviceaccount.yaml | 14 + .../templates/test_receiver.yaml | 53 + .../104.1.2+up4.8.0/templates/userrole.yaml | 39 + .../104.1.2+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.2+up4.8.0/values.yaml | 484 + .../104.1.2+up57.0.3/Chart.yaml | 10 + .../104.1.2+up57.0.3/README.md | 24 + .../104.1.2+up57.0.3/files/crd-manifest.tgz | Bin 0 -> 308570 bytes .../104.1.2+up57.0.3/templates/_helpers.tpl | 30 + .../104.1.2+up57.0.3/templates/jobs.yaml | 102 + .../104.1.2+up57.0.3/templates/manifest.yaml | 8 + .../104.1.2+up57.0.3/templates/rbac.yaml | 76 + .../templates/validate-psp-install.yaml | 7 + .../104.1.2+up57.0.3/values.yaml | 17 + .../104.1.2+up57.0.3/.editorconfig | 5 + .../104.1.2+up57.0.3/.helmignore | 29 + .../104.1.2+up57.0.3/CHANGELOG.md | 47 + .../104.1.2+up57.0.3/CONTRIBUTING.md | 12 + .../104.1.2+up57.0.3/Chart.yaml | 126 + .../104.1.2+up57.0.3/README.md | 1080 + .../104.1.2+up57.0.3/app-README.md | 46 + .../charts/grafana/.helmignore | 23 + .../charts/grafana/Chart.yaml | 39 + .../104.1.2+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.2+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.2+up57.0.3/templates/NOTES.txt | 4 + .../104.1.2+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.2+up57.0.3/values.yaml | 5431 ++++ index.yaml | 192 + release.yaml | 22 +- 650 files changed, 192278 insertions(+), 14 deletions(-) create mode 100644 assets/rancher-logging-crd/rancher-logging-crd-104.1.2+up4.8.0.tgz create mode 100644 assets/rancher-logging/rancher-logging-104.1.2+up4.8.0.tgz create mode 100644 assets/rancher-monitoring-crd/rancher-monitoring-crd-104.1.2+up57.0.3.tgz create mode 100644 assets/rancher-monitoring/rancher-monitoring-104.1.2+up57.0.3.tgz create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/Chart.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/README.md create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging-extensions.banzaicloud.io_eventtailers.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging-extensions.banzaicloud.io_hosttailers.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_clusterflows.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_clusteroutputs.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_flows.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_fluentbitagents.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_fluentdconfigs.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_loggingroutes.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_loggings.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_nodeagents.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_outputs.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_syslogngclusterflows.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_syslogngclusteroutputs.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_syslogngconfigs.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_syslogngflows.yaml create mode 100644 charts/rancher-logging-crd/104.1.2+up4.8.0/templates/logging.banzaicloud.io_syslogngoutputs.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/.helmignore create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/Chart.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/README.md create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/app-readme.md create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/NOTES.txt create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/_generic_fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/_generic_logging.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/_helpers.tpl create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/clusterrole.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/clusterrolebinding.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/crds.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/deployment.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/extra-manifests.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/logging/clusterflows.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/logging/clusteroutputs.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/logging/eventtailer.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/logging/fluentbit.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/logging/hosttailer.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/logging/logging.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/aks/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/aks/logging.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/eks/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/eks/logging.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/gke/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/gke/logging.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/k3s/configmap.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/k3s/daemonset.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/k3s/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/k3s/logging-k3s-openrc.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/kube-audit/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/kube-audit/logging.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/rke/configmap.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/rke/daemonset.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/rke2/configmap.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/rke2/daemonset.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/root/fluentbitagent.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/root/logging.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/service.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/service_monitor.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/serviceaccount.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/test_receiver.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/userrole.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/userroles.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/validate-install-crd.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/validate-install.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/templates/validate-psp-install.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/values-logging-example.yaml create mode 100644 charts/rancher-logging/104.1.2+up4.8.0/values.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/Chart.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/README.md create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/files/crd-manifest.tgz create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/jobs.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/manifest.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/rbac.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring-crd/104.1.2+up57.0.3/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/.editorconfig create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/CHANGELOG.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/CONTRIBUTING.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/app-README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/dashboards/custom-dashboard.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/_config.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/_pod.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/configSecret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/configmap-dashboard-provider.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/dashboards-json-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/extra-manifests.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/headless-service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/hpa.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/image-renderer-deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/image-renderer-hpa.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/image-renderer-network-policy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/image-renderer-service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/image-renderer-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/ingress.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/nginx-config.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/poddisruptionbudget.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/podsecuritypolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/pvc.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/secret-env.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/statefulset.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/tests/test-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/tests/test-podsecuritypolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/tests/test-role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/tests/test-rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/tests/test-serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/tests/test.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/crs-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/extra-manifests.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/kubeconfig-secret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/pdb.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/podsecuritypolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/rbac-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/certmanager.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/pdb.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/daemonset.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/extra-manifests.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/podmonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/rbac-configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/pushprox-clients.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/.helmignore create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/Chart.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/README.md create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/scripts/configure-firewall.ps1 create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/config.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/daemonset.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/podmonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/scriptConfig.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/values.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/ingress-nginx/nginx.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/ingress-nginx/request-handling-performance.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/cluster/rancher-cluster-nodes.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/cluster/rancher-cluster.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/bundle.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/bundledeployment.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/cluster.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/clustergroup.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/controller-runtime.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/gitrepo.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/home/rancher-default-home.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/k8s/rancher-etcd-nodes.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/k8s/rancher-etcd.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/k8s/rancher-k8s-components-nodes.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/k8s/rancher-k8s-components.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/nodes/rancher-node-detail.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/nodes/rancher-node.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/performance/performance-debugging.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/pods/rancher-pod-containers.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/pods/rancher-pod.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/workloads/rancher-workload-pods.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/workloads/rancher-workload.json create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/files/upgrade/scripts/delete-workloads-with-old-labels.sh create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/NOTES.txt create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/_helpers.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/alertmanager.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/extrasecret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/ingress.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/ingressperreplica.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/podDisruptionBudget.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/psp-role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/psp-rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/serviceperreplica.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/core-dns/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/core-dns/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-api-server/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-controller-manager/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-controller-manager/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-controller-manager/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-dns/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-dns/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-etcd/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-etcd/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-etcd/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-proxy/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-proxy/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-proxy/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-scheduler/endpoints.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-scheduler/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-scheduler/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-state-metrics/validate.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kubelet/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/node-exporter/validate.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/extra-objects.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/configmap-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/configmaps-datasources.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/alertmanager-overview.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/apiserver.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/cluster-total.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/controller-manager.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/etcd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/grafana-overview.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-coredns.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-node.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/kubelet.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-pod.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-workload.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/node-rsrc-use.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/nodes-darwin.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/nodes.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/pod-total.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/prometheus.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/scheduler.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/dashboards-1.14/workload-total.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/namespaces.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/_prometheus-operator.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/certmanager.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/ciliumnetworkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/deployment.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/psp-clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/psp-clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/verticalpodautoscaler.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/_rules.tpl create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/additionalAlertRelabelConfigs.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/additionalAlertmanagerConfigs.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/additionalPrometheusRules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/additionalScrapeConfigs.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/ciliumnetworkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/csi-secret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/extrasecret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/ingress.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/ingressThanosSidecar.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/ingressperreplica.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/networkpolicy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/nginx-config.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/podDisruptionBudget.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/podmonitors.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/prometheus.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/psp-clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/psp-clusterrolebinding.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/psp.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/alertmanager.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/config-reloaders.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/etcd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/general.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kube-state-metrics.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubelet.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-apps.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-resources.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-storage.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/node-exporter.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/node-exporter.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/node-network.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/node.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/prometheus-operator.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/prometheus.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/windows.node.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/rules-1.14/windows.pod.rules.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/serviceThanosSidecar.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/serviceThanosSidecarExternal.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/servicemonitorThanosSidecar.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/servicemonitors.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/serviceperreplica.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/clusterrole.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/config-role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboard-role.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/hardened.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/upgrade/configmap.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/upgrade/job.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/upgrade/rbac.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/extrasecret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/ingress.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/podDisruptionBudget.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/ruler.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/secret.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/service.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/serviceaccount.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/servicemonitor.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/validate-install-crd.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/templates/validate-psp-install.yaml create mode 100644 charts/rancher-monitoring/104.1.2+up57.0.3/values.yaml diff --git a/assets/rancher-logging-crd/rancher-logging-crd-104.1.2+up4.8.0.tgz b/assets/rancher-logging-crd/rancher-logging-crd-104.1.2+up4.8.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..36ba43d8ad011dd9c674d4becaa609bcd3223557 GIT binary patch literal 170045 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 z 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%0D>__=!Dd4UC^W7Y4p|#Z~ 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¬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

A{)|p-R2@=#AJQ4Q=Xea9WIdlx9Xqc5($Nh7 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 OwVp+bw#*T;&f15Mq= zEj%cCW0yayAiQVDj)^s%R08K-k< zJSguq=6)*_ExB59y}|$XQofa?^@qIg7rL=xsNX&**SdPCRrk6Bv1>70`y>0!XUnE3 z!CnP)QPv8)<#Ve{E@)=^+Vu0Lo1JIf%+3F-EeMSXgzhLXcD{m`6SOGkYxpB8q|Ml? zfwmqDz*Qt;5DY*CdBep^e7;d+Q)pXa%H-JUf4O{`9%lK+q>d6+7!V8U5|2bMlW~h*(if2Aq$hjw#q4Q+S4kYJVhf+_rw5i4T!`&G-3}52E4QrpoogSM7c60^tFDRnnA=D&{8&E))O zLfvCpS1Se9<2-D2$Lptn+fR(UrC-7_z1sR>k365o7ti+gX>8mLjucDX^PUHtc2Frx zPV;GiyM@xUgsIPk}0v=o(!;i@JlK3!%>r7{BQ)G zDyPtxqT+Stcc}liy%squ^dVxk?i3}oJ*jeIe_Hzh$=A@EWCc#PVrNIfPDVuBHHElf z6w-rXr-9#nAlJB zls;Ii$$fG11(}g2ry9!zUL!a}Uo zJChEjuA#hzuIIi=-NW!?Ayam-Tynw7?Ul@U5*Mij#pIgrc|3Y8@5w#GZ3oorUH=t$ z)cr}E>;K_!3;2{{bw+BnEN4h0S8&YVe3-+AM$e*Q<#dDN;1(erztgLq$LCch1 z)V;-+6~yI(b>jKH(4B1~%glU-Kl(#IPXu3vW3)cI0UpEAfZ7bY(tm|*3kcL21Lm#! zG|Si>%iKk<{VY5r4_#u7VV8QDic5hg7P@B3jIMg`%Akcq@9YhPaE!eK{#&6d0H5fm z0~kIMME6d#4k3?+?ua>>y349GUps@ULMy`%^-nCt2ZM%4G_>s4 zEz~+{_MBKtRSLRcNBs&T?5f5*youK8Xxe0ZyCc#wEl_$N3~3BU?#pzbUfIcwez_j_VPyrA4S*Yy# zir+!e@fZUi8bjAC%Spk~D$t$-CJEgB!nX!MzJV+Hc+@z^BW(TAf5{t6n=gUBVVSoj zVRx+9l3Xgx9R(6kmEtS03HkPyHZBb`NLZa!wvLRpbp%!%*&xpkX%Fy>_+h)%km66i zIDdNnbVtGO1?nsQSMYzeRo?#ha@k=g2}CxSH8pNZq~Sj3Q+Nh;^e;|pyFU5i{Mq@_ z6TRkVr+W3CW&YXh=_v`+k8D6RD`To*o4*vMOy9jMQWHaN4zU+(0^JI&XLn=yEnGkE z#@CHd7x7VKC3NblhE+Rpn--vcB#6t^_9=D^Osl|gni+a>KCPwg8EU(ke$ z)e9+>d^HgNe*Ee`u3o*neDmt<&Bg2Iwhlc6PFRfVZ=jA{N}jCmJd^XfFP4>>D1 zlZTg#>TvW zhn<6meaK~D64eTtFf}LFRc_(dj6y# zc54G++)m`ihGxa=NBuMgaA~sYcEE!LpY07myIC`&Y^u3?8fD(Ee&qQcd!t|5X9Ji> zbIC#iSLdGMHhya;2*DiS?FXSChdsP}PjAf7fUdzCLc>a663!RCoVB~$x z#Hw6BCr|fT;F{5t^`()FiC7#IRNHx;CiDto5seZDH;F1cso}N(z|dFku3qSS^XHqJ zD_gjt2e}5~?YK}Zsfw7pf4L+nSD@Zot_H*a%srK25I?73X$mP=(qB6c=d_SAW1T{q z(sB?NtFH?RPSjF($NP4f;w`nrrJ$Z@?2&Ku(` zqGXv#Y6_=6A?3P|)oM+icE9(D)rZ}qDs0I&Oja?3<&B9ZvUMO0qp^*v?N6 zWpAw;d~a|=pZvq_!|Ar(lhb?e->LWSwfFCh_iyF@u1^1W+P!r{xqg}I6H<0I>gM$| zF=9z6;Sz#1RhjZbhADS1e~`WPZbM5Uw4UwS$7%8=8+uaC%|iu|d;N9+Q^T?r&U6A5&4|r^`Ju@x^rr?}Mhli1B4~ zj^BFaZ%n7%a&#Y7dB=)7&hF3eWuYbBnP!JGP* zRf;XE3{@jFCp72ZVS$q~a?6L?m+MjS^p6i(%Sh%Zjf~vwYskli-V?AiQz^}$wk!xA zY*j}P?_6v{T#J!m=3bA7N`E=DOHm+N7l&d=!Fr3I;AqJT`h@`!^63x>b1QL~Uev!9 zOy(%BL?8=DG*~9cK)PkU6(#C1k)3~TvSaQ7(wxD&jN@ldb0WYe^lKh!x7n+{5!BeMy~56`Z#RHsV`~*EgFy{V=(8IZ4cXMtQGM|?DH+#UJr1y0Z!Jn zu3@2gaPDz@Zji@45`Wu+w?$IhVV?FW^RuzMEP_)-?pqv(8qb}8_Y7l03}=etO2Zr} z%#ETr(LP)Voj>6c{Ehwn)`Xd${|L6%hR8l34GXTfe=}z;Qex*%0f?q#`at~AkwJ1O zUtim2u-1Rd@=R`R5gAtks8XGm3j)sdMJ_g&H(N@wVxq1$>%qS+X{oQWE|*x>wl2lpC{9F`sy56P!Yi37NtLUzV6?06$zA8t=^f=6@MT*V8=5HE zjNbaC&MojJb5E5Gr%F3g3If=Iol4%wYPf#t(Rbdnm}stSdTYI>P=?vXn{-UvhXNbj z0P70%=Q$ImHYpNK|FI6RMrb(B-S!^W!ogYHuHB+Zih=Z)e%!sq*VvI<6GVges$+BG zO6q&F_X?j-veCcj3jo!tP3I)dXL_RhX}zd@D&E8AwCoiXT@FGTPR1Uz5w>XQWe=Ht zdjpNHp~nvtKsCYyTrUHX96#^v$T~>ta8ZTK>5BG8*0k%ZwO*=AvSQ%;#-Motu`%#e zsIHSOU!_U8##wKxObD5YpQT$u3t0(MsHPX9tEv5_HPN?T|9F$X--s+O>FJHBxT{~9+1U89sMs0)bYJk2 zMU+iHS<*}~E&o))F@)1*9ej8sysVIrqpHQ;_tIQIK*IW3Iutzamrom4w{b=Nr5zoS z6MXVmkwVJybnoLc%Y5}Ak1Nm&ZP_&+$Ya*ryH0N}0&D)t6lYL;!!ufB+fW?-HLe7r z*_pWGg@oJ+az_iy3ov>|!W8*mC*NJX`|I0_H?K}LMd^jf>}u;iDE`d7&$JJyA9Y&? zXXmX?0BDn4ho*F!s;p?1Z3+7TX^eOK-qV3#ddr16|ElRsm%y`Mggh>PNVY+u6f4zO zpdGU`mD6Qa=2h8{JwX>T&2sJM>K1iI?&*NID+!se56d*Z1k*KFBhwrt(liSu>$6K; z173lhJZx?BZtcu;Wl{dh=Mr2xD*PD%% z3UcxNHF?R^t?TgLudM0iw|Xa0qE*d|K?(~94YqT$s}00H%wc|uIRfL`1%8J}m4B!V! zGbcAZe@1yU3gb2ANa>Ko@U~ox7wy`M77^G;2bOo}5qwW=prrr+?ktCQruSW-hUM`8m z5|d}98YWgA;L1G|1i9GSuWJhIAt4l4G=Dlz+1C-cq0%FR51E;Z0s>spPqdB>@ z^3j>UZueXe;!+lFB9Ns01!G2{UGBd?dI#ij}3wy=&S@J|cl9(MDN>e)%$fpX?jhKbrr&V&w9r zCGcJg|CFoS;6_=dt9MFs;**OF{ZR_?>Z@xrt<#@q(}I*|$c#O6dm5Cx19oisV^uIM zmqZCV?&-F0qkktaX-QGW0SXk#A$AN=i!Tdko&&FVLdpU1L;_@g^+u*6gbME^OS1p0 zXZQktCmRioyp@85g9qL*nnJtKGyLcG1ut2U8bz@njp9R{dm9U~FWANSJ}wBH(GM72 z6lNBgTo8lo53!1G-(8Mc#JBG*?Hcqy<#K2GFvT#Te30MV;{lw%dv)>h z&8zt){pDKT&q_I~6r1rf#2F(RrA5YB#k3d81MWT2VQwnddJDg?5nLEJL`{DW>)4dC z3~Mh1HBnsDnBS@_!@VvG#?E|8)A`4jB5K1)W2pl&#h|(d5FeTikdK3uW4KK?;I_Tj z^*hbozHaP3G^vk%0lC2(ZnTICa?+Tm14ylKmDm}?hvDc$-ZMfby)hh z_8nVx?X3CP`Gdm*2PLp(j-M3=I=33zP5$(I8=Hd@lb`Y_NAo^PJnu+OGni7bUqXex ztMN#$pVkN{eHK+%S+Ag}geau~PCU$|Jane%hKo;z8Vt*rR%F>*e&izU-}RPB6P|4f zkmfhzgmFIRP$^$4JxF1_&`lq7=iO>=|7NTHp3U&Pqn!1` zjWW#*O%{R0xO@*jH}VmrzfV%{kK&sLY-gN|x4#@x(`AV0SGF_xpeTma%1>v?X+bxv zWJTQv&D6uw|NJIr;<}{CZO|(+$p@dkd~krn*P;!!2QY~*b)Xntpr7(K{=|OU!7?08 zOOmTn(3Az-&)9$vLtJy2LtEnBEx-mFq427hyK89pI47<5Qj=tD^e+ouI)W2+2eJ~o zv|{^lE!iZdQx-6FuMg9_E>$^TlS)e4#KJXuee&eV6Kurz<(FR)SrAH6mhesc!60CS z@SCSk=j8ugym<}bk9n!Eku!c(KhOXiXt$@wzh8gzwr*+Fd=s=rx1Ei^;qWwn`|DrN z$xB{9VRdf0&e(`d8!{|pNhq}U12HMA+pe+BdkO9TFin83)}?9up|LmPNr~lPk#x#| z<~YPg{ox#(7zhhKBN@MCWU2mC$SSY<$YX$P5TjR+b6+$dsD`_v|N@FMVwcK;Yb)>e&e1*7Fi5;HHkKla48C(%3Wmf=znZ zzvLf?dhwOFVk~_Th&0|@lPDf%Nl=`eyl@G3Hh}0-l&o0Ngq`{p29~ech82Nk)ixN? z=De+`NKK2_gcU$Y*oTr8`Yc{tUy`)ocdSt4-mo|Pr#Sr1C`-%OPYmu z;^Rm@n5?N@SyDt&89#HjTrB#r^YaonmxegA~ z-7hq{cDeLNBL~-H%C6YnIw;$Ki@WX~lv8D_iQp<9>Mn!BJ2q6YKss_&9~x;_v8jQQ z&^*tA&iAOj7BXd5)gt3+eLdRf-}N#EUpbY1s3|US-i8j_zhXjhkV{$>cl0p~?N9r{ zNXY5Sn5omF|Ma$=|98VFo?2GaZ+t6q{~eOhEK}`z7?$jZWpoV^RM>^ZG_H}*?g)f# zpj0u(cEoJF6Gf4Y#N<;!q_6eHx?3i9={u~C+vayxz8G&4*Rd*m`Gqb^ocg-R! z)b8T$62@960C@m^4AgCb3CpB{j*CE#n@#%Av@m=!LDY>%kbrsaE7qp+Ufk0ny}0Vl zA8U$a_4B?^YJVpBce;SK_?W{GaCq%{$9_sLSeJp#l)-L$vVthl>E#NU?}!@UVtY8% z&{7tJIyu!Qr`qS?RJ%l{n&zY#S5Q=^L2qmss<4%Atl#2gP3cg)ZKr*ClK7A$Bh96) zPq9^|IG3h#@&kE50M>v4)3N5`I)wzAd82dC^FZcuz^sP@gdHk`M9!$rutT^yLoHt8 zD@c|(O<1rRS3MkKjW93AZxn&*PF6gPdAePJsjezonlAVo3jh3C?^{oWt**fp(ZXEG zu$T!eHj2pQStBm*=s`AK&zvQ;={{_T7BRPQSomlQ7%@=V!#-ni2qW&#>w3NVsu@pW%v~)S?!)8b`TQ6IKWc@cDwnh05hfCu#(Jss91B%~ zSXG;%eCO%L&Uchs66g1zEn;k)qObQ9ifU2FRXj2ac104SWg-hfk&JIR6c0#UqjhqE zKhBf9ilG_i=?&Y+VtZEiYftj30oOcn8bdD&Mv|&1m?*RDBg$NE=Z2Em>(M-v+Fb_b zQ^(VR7MrxBm^~z(D-&CPi#u{h3pKoAGG5F|`5jj>3SEMI=-VTvFMZ!T(Ub3NQo&9A zeN$}}DYLmBk=t*IY}R+9CG$QFm&UQ<6YFE&9((k)Zx6dc``nkBNjW0sr1VEX^)Vv$ zVDZ-G3?5y=j*VaWc+n|?fWT$;l1HX6+NYa|3nkm+vY^G5q{cM19Z~?8G%i&1rIrT9VsNY^>tt*&ZDkKlp~x zAzL7tq9G7MrcCd*1%z{In19iQ8gW-o43JYTC%yqO;n9zeL>B?zKeE?a#tAy3hPY%r zZ;a-Mt%N^2O&h6FO3*V+IhiHNWJ0rua(SdF#Q^fWvUk-w0yPThFQW7ZX3t^OKuzBdd{b>mr8JUDVV(&>H8;jh@ZQ$)hvFz)0KlgHJ|q)dyPd2} zL6A{u)k{@@vSC($@^28LT!MSwiJQt*MBllLf@kr!(H5|FhfoO?z?4 zGdCOY7RB9;+~ZC5=2eFFg5r9Yv)B@93%107mHu0!VS#>a(qU4Tu@W*^m@C_l(K8!)r;+mqLB3V!Xzh2;ET0p4 z+Q<%7sJ;ruQp}IZm;+x_LY79|})Py(t$JR{oDc6OpR{ioDb#EsbRd#nf;TkPjk#sBQ zaOy6`)hRBG_Xp-dD7kW_m(kz!BBOjmP84J0l|^a%%XL^>Mr&lzj1`lveU!jjU>;E( z^0}J={CWpECwc17s`JnN=uki$mhCOTL@K?wj*F{H$PyLZU>CiP zMr}A^2=PMx#`dI9u;H4 zL|F_}*t(Lb*GU=YT(G~{=m|J7XSYpg$;4p5vdxASvNTO~m*Ae#dvXHSLM(o8MoKAx z?f@+e!n_cKec%czq2S)a(NGLFcLIw3q{akW_$G{~(xA|K z63rCzg3YWrG=%(J1l1G`%B6{7*I!ywjO@zO!NtSbP+_iQJC+;PE=5v{LU6DH1#RAf z1e9$})DT(=j9*8vgegUf?HTkm#)#VRT=fZTsKD-F1xut*Wl<$?Qj{zTdCP=L zP0-xnCL{zB8x?>jVV)!m%v0K;k@J zKL}UT^lZ4>vE4$R^)enZ!cVbbB~58bM@448p{{e5iFknx^CDs5ayFeNAaf3BCEkX? zIl~@7Ev0f!-pWW%D+XkPs0>}!utu5t8WKyElC%P8JfbIXSf)0$?lSgGpZOyp;pFdFH_SZ;vX!7&U% zrN&s%tr*}TDrxwV=DtIVALF9KesFJO8t2bzwQj3lu9Gh?xkrI{3m=GbJ8S?-+3s;m z*7RYBH+vf65{ZZ?v}2^FEhb;p4o#!3quoNS%0KR1L+VZ3hKme} zXisGaJ4}xUYt)-g8p*UxvmHf3N zUVus6rc7#tE@YOm0=CO&|8Z#0sA2*gSJ3r!=FC4%RT1ny3Z|9MsKRQJHZB3oUN$Px zelyN-SkDU^Bm;~KvBk}N=^+goe4?PP^s=XKV{$a@Xspt2yY0A2M<&?_8%Nfq4y^n8QgJL05xgS z%0uKPO=?v$5Gr;Bq|rEC`blt3)&={6{@NMg{T5n(P$Hz5nPh$EyfJdOjUYyw0u^zR zoe|n#wm$fat4l+qPlOam_VC#_!3`~GoyrY@angs)Cy(W@URfq99&wRsegJF{3>m6Q z5*B%tjM>odgj}-#vppMHCTpgMl2PbR2p6iPSyuPzHV7a=;xxV_Ul5HW;a>K=v4G|o zH72TMB@zsE09Fl!Ryw{!PeN^7h$E>Mk-##yMJ~Fwoo7K&Hq`{bmT?h{ z3!2>C(;`(+;DDAKJGPyn)aDCV;`li3iq^->MO)7F7kyIyE$*7OWzd?(|2I?d?hfupDSyc zG|4q5X(97GR#4Koe%f9=gn<-yOhGV^P5KG7XYj|030BY&9G|9wCtnh}Gu6gb*n1;< zG(ab_J<^es+BH7Dt<0>S}XW{CP(~d{IcH-deDIW)QoCSObGy=A?;Fnt0dpCQZC+{2VlK zkB05NR41J^jf>u*_rAd7tt?HT0!Y@BjI)7~9W9Ll?YyVkxnQNKM`e8i@9cN~RM3GU zO)S2;!=D~c^2ytvZzu!g`ibkGd^LY7t#@QbKD!V0jBnshG_yr^Mc)RS;g&x zNn@x=lrU6jboDh~xz4UOR2f2ViZosu#*kuKR;pQRC4qp32Xt|}vwsYU6O%Dw+12+;f8sU-agI^7^yr9y?$a&Oraj}%{@VO$Fg2=+`?jBdbOcJMO z-3zrhd?dt<`I!TkMdJh?Y^u%&K9K6OI}i@oPa%TDrG-ETpR^ z`>T44ioABF5m+F&j>x17ivx}h~i?EF&~CC>v^Ax2CHYJ^`yU7{ElV}^BJjdJ>TSV zNB)eb7TDxfiv%vW@936okIve3DH`I@r8uhVe>P~4li?ty;RyZ~S-zN=xT@$`$pQR5Cni_|h4kU3U!UnCv(cp-agX!)vQbTCy|jhq%ma+mvV~ zw2>)anh3&c&l!4##UxBU2)_t(6j-~x59dV1|JDRAi9U&TG-G!h<^DJth@^ZZPCC?K z$&QY`UQpfM7C>v1+Keb5V+Ze*SH1&!DwpKzxHgg=M7}|yiAe*pBwQp}m16u5l2A>n zV(9!HTe_DtQom|tK%4L4LW^Pvd>7$`#0rPANnD+UQLB%XyknH?8JtewfrxJnKC{^alT?y>27yRgPKC?@71J@tTRkM@ zC32G&a>H$uyv2!w3-D%Duq9ISgtJQMBIII8{N9| z*!AvgtYZJhn}ocx5FrBzWXPo~5*y-aTZLldIDPWp8QxflQU#fITvJcn{_nqk8{cg0 zxPGVaH1B1RrT07?F7l?xi3W5UT1kXycT^|Xu<`Q#o~I)=10HW~f>nL>CJ?;~gr`iD z`f?XxIqd|Xosw4^OY#A1XwR})a8cKHtPfzw3#9LrHS{Z1V$m=t`XI|SQG8QnB^69o zD%%Fp>0=(kFmuh=2fPSzOx8W#WVVpD#S?pAgKC2fP^mL+({smpUC})DfhDHcN}g3K z-dh^$qxQqETYFauihPHU((8nOD2v#yMg8X~2HbSErza`PnHZ?&B?bAq##7vogZJL_ z@%rgoH6PoKVhxVrX}D{drHZf*WkG`;j6#F8tzm;Iz9q8gG6Nfx9aFhj;jez)~qzxCLr?8$K=#CG2^Yr zd~80|Xe*n%W5pe3_va?#Yj)4e^~@wIpMwB-{!94JptS*&s*5x=Ih$B7)l_Ggdo5ni zAhqX=R6PCTkX3Ay$TMiX*vDP?*zMn!P_Q?yZIF4kWzjG{8X?QGRP}f`UvhOD*M@87wdU3O(~DQc{2HmbblVAs42At* zWnD4;z@9d%gw?K;l&jlAT6^tpdTi?pw(~^Y8YYNuTUn8NQ()ZaDK|WSPF@LB6|8Ow z)cVX24o7M&+E^HE)g_{TjwLLi^C$fMUB~*}%*}`Im!fa717|_{17TF^Y zZvM{GQKHK+KJT$q-@J77vUXMts3m`T@oG-KHL8qZ%ShGq`ZZ3&6CZP9qpt1&7J?Xk zKFkAJy8f=u;iuTJusvZ|GeL~nTc+aWJC^r`8@41Ve7I%*<)!{XDh{noX-Oy&lcdUM z$Zv$!-#K~t>gwIA7Z*3LUOp#(GGE}n@H{6svNjh76dsrIXBvvQxt$>qCREgY6ru9~ z735Oz(sj8G%YI2Fg$Wr>E#Ub2>3G)&C=f+n8KpDBhrmk-4y@rM;ZOXPljaL#} z4_aH82%S&$@5qt{4aGt_I}MQqHp?@u=I8U{Ipky<&yTGjmf2v*AW*}b>dE;1o0^C> zC*&KO+!~hH_)fg03$v_SSay72h_-;;s#^GyHDQ}8erIYq9&C%QrxSg|-sQAv;Jep{ z&jWAch*_8xUuF)8+-$HLM7vXPFV5HW8z(!qZQHhO+qP}nwrxB4#@MmBW7|3P|GiJu zxtZ#o&(zeq=<2&QyP3utL*sZ(2{5w3EUyib5Rlbtf>~&OooYX;@#`%s>MoFz_U3d2 zUdAreDB+gKLD!jD4PmCe-j=)g+Np`jaL}LSI42^Fj$+Nw4V7VS{jl89puJfq=#|$m z|54U7cmC9z(lvKp*$MF)75_pGNwRP)_jq$`E7wg}w47?&N%S_8&t_O#+yE1JA12VG zw7nfq3@{nGGZqRMbiQ^wn9^!G$oyPNL?7W+ZXkX4#PO{}Jg?Ur$lTZq3rK{uj&?;8 zygAv}tjG~%WLTeZE6{p~6?(Rxw)ynyC}w}woX%}KI@sE1N1HmGH10DT3Y|-<(#kR0 z>P9MTieEr;52uQ)AZ2*Nn_s6kh0=9tdZ@O1Z|jon>n5lb?F*Pp6los=0L+HLNz~?{ISM z0w*+GFoBQb*m)ALu8GhGfSg?OQM9zN^H45|NP5gvmr9>gDQ?e+joIpsT2#&^j*2}K z(EOsqggeD(?HUonbYy&HkkHB+Dy+TTD4@$?9K!Es4sZpl!AV>XI82kMe1Tlhtw$a^ zf}-c$ENlu2QAq@EjS8 zorJtp?*%v6{pXBfn1=z)jd=B5wxB(!cyMC=^@xRZwL25F^*VVQr-jt*XByy%zti7q zuV%^9kFBFb9A-GFxU}6#^6taCaTI_-CqqU5{HxA7a_#epXx@MF0+_GA&(5>-gLTO3 zD^&(v)K|?+O9MxfF3?#raJJ3O1ss>kJ`@Jr4!IaMOTQgL&pkpU9JNgc{gFEl$_or! zxksma?ByW{_|drIc*v%Kn#H=1KtOOY+Z+x)b}vhl&;Ly;x4Osmy8A1sJZ3oDX*VVq z_Gny?y0!hp-RkcEZ7emoVcn>qA#CgY$EWuu9>qN9!iCM|CK?wtSWFlM9ADWE!5$`)jRnG&ks-}iHQ8PlNO7w$K5 zmL4e9tcz3SThIx3)7kPEfJl%V<-Qi3)}xr%YG}a8@5W2e9RM%8uHsR3L!REn^Cb1D z&;?_oOT!oH2fMyG{`uaDVWG#VqU>$jGM+Mt$Z`-ah_Nf|PS z!FF2_Z+2pJJ#t&R0Nh5@a4gfafdA8gC(Z{l(six$Da-TSZqXBgp1e^7ZRaXn84S)N)nL z1|>dJ)S59b7Wsw;TMJUq_)P$3kh``}A=+GO8>vTD;vr+hS|lCu9czjCL!6Rq-rhz= zbBhHdlcJE%E3|c#!Z7faEEv+5O6I!+A$(W0$Lq&U@q2qHM_F2s>D~oRqka&(FX%gX z5&QM|%;9j!U3JnRG+2(@H;&Yi=ko9uX5i7zuT>YpT{GBua=J`oGo3~T%XSE|5@h@(dl`0Xj=TD&k-y~Cr7~7$ z^=@~K&dx&s9e5>k?%A(6c%eF#g;K;Jr0(<>QmC;00c)8rp32mov~uU&v*LD5Iljv6 zGvqAr)V!ggzzLPkR-|g*a>1YP5b~UWQ4*4p`GM%SC2H;2zug+CWa@U1M@XS~24=7Iwiei{|+meyn`g|A_<5OL$ z`%}^88}8%$mJc(xny@X6peovO0$}R-M9Qb&G)?yNNcAF;6BC@l5+p(*N5R#j)sTLH z8+bJB5bmhk_i*s9*8^PTpcbr>$d(2hiy!pgvdu}&= z^@cgX+3I`bH#b3<$!W>c6>p)EH43oeM#^WS$MKfc#aj1mLR+8zttZO(Z4yfxwjeRY=L zauSuYP0KXC>Z*!yap6_XMaAo*c)Me_jP~ufH@;=vp2~GBsWMLbI4_C}D)fNr2T!y; zn1i($*H=dQ zIcXgC-3WmO&mvaL!mS@~R0L7Tcbx15SE{bpFMjw?dQ-K{E6p#TQFkHmCuQy1El`{a ziAwTWRdpyn%klnPB=M9s^dWP?W6{G@bj~`{cV&jv_o+=^i_v-{1g*ZnKSv%;OzKl$ zSYyIqSSp@KgR2l0H`(7(VG6oYuXj@mzPGueAEYiCNuuR z26U1K8Z)RG<*W6lWK|7b$TCfw>?dr9bmW~Q{4sPFiU?y<)PQs0DBwQra#VIxavbgL z=4C1MrV7_Gj`=JK=;wEm*qd zpE09pw_Xu=$hfnTe+hn9^CWije(n}6@-8{!n$9oE%N$94K|B?HuuRl(k zsp{o($49xdyfIXV{UO*x>A_2P@Hs*x($9_h?J7+wtp&jd^BbVWDjjz4+lJ zSa=sJcy!p=8jhDNJ_k!iJb6WKZO z`t3$h_p}C4Bu7alOVm5OBRnAg6h7^8C3)~{%3FHu?xdl{#sU%5V%%*}2 zJtSmNuBkNqvAqzkdcQJnN539$v;}Y{#6PWv(ahphDDQY(N%5OQS#V^EV`R)BcMD_B0YOQzRo? z@ULP=oHN8rMo~?xX-XBS&7-+mO%}DzXw9RVms6aX2#K5Rpe)oYcBm6XGO)QTl#wIp zn0wvK(5{2XD0vJWFf7yo_N`*nwoyb zYsGxAEC4Js(?!chH(%ZYf&?zSwVuIBJGHLd?|8jSclF@h^6DyswDq#6fj1G zhl?4Y9EWvr^eq-h#a|~0gp;7|xo}G&7v^=# zcc*ji#p;$#+>!vZ!}#q*V$Fdnn=3lqim&*Z`z$0?+W{;$HmKG0?U+W6yFSx9zjxJ(5>}FV*8>Okr&&uG;vvf)D@zBx<0lhVTFt_|6u-YI1V7INElUFV zxnHL#8^1pd0etU9@V{>>=L8DBM!$f8{QUnRgWa$5lZ%yr`=x-dic0p5w}Bt0hk~n> z05K3QzVD-7Y_7#{{XsFVlrh+ZCoWOJco2(@&qg1;mY;6EX-@EHi9d)!}41C4}=pR``zu z*?7;xt$+^a$7k4xrQwd|iG#+)tAb*9u%9a^+YXq-s^pZcRZ=%GGgVSIQOnr>^Gqhu z$~nc$_=M7MY3=cvZ4+ZzKe}#(n*u7i*?*zZ8)Hb5(kLB{>0+P+tu~O|2?b-S+UW7wNY)ee+bZY{@E^zHRTG4&bh zd|=hh8zRJH)e5+Zy!0irYqK8A{n-y&<^K3+Y_r#>>lP{lCAOtz+DQ?~Xp5UH+#vha zHWw@tM1@8Y>uA{)@x`z%-M<9+U=Z!LlC~_jzkKbW)cum5wAF7Y>d?CR?XE%7(r;IBU_$JRDeo1)Q5FKEK>+Oe5lDg{Qben@N~{+Zbt zN&(>vk$AF%qwn@sSx1So`e1lH+s6of6SNC~X+Nx{9lwI=Ul5g7p_W27RWT!*XX)S> z66m@dt>)&`5<&p3!7)GbbfGr0wLo z(wvR6_Rqq20oa_ITfuz@mC@yvG&45RBg2zE4v0QV7M=|5dP2u0im^|M zVme{k?Kic;`Q&faGeP>tZ)4JgSme})KQgan{|ck3oc%1~U~kndeF`S#!ar;nBdtxI zbZVB$VZX$eD#ESSSaj|0Ie2$@kgkN*zFKI0&JyB+ zla$gW;C+~~wbv~Eg4(%*x1-ac9rk9=R$P0?FHPPSnHb7j-5IQDsAU`DnK2_8(aD>T z)1QFTNUzIuw}*V)KgQ|C4vN3)WZ@p%87+`4YvzP`t=xKbb5^HfKN?!^s080@ zrUL^JXV~anSooIyBd-6Z2ZM9l@BLnf-HhX9{LDp@@)-K>(goBn!1!r!t0gHoqdC$+ z!qs+9kUn#QmZi`5IJwvGeKQDm=lLUOjR46Rxrz|LndD3rLLa3*ZBEs4(iUuRr|uQ0 zLJL8C;YV!wG)T9x1qV4Ys_)A2_WaQh&}xT$(~^%`iz^9i)uGMN5a@ryg>9u)pGD~v zoUX@)>v)zz@7yI?M{Gv*)KBF(h3fQFB|c0jInCoMyT$9!fuJt2 z)M_ZL1#R6(+Bq6iBlAE3=H^-OAe>I=-=B&z6%qt}jo%%Iab4^Sfzy&n0~vuSD5K>` z=1)`Cf$jG|VGGwsg6zj%R|JTWZ5ut__-7jpEPit)63wM=$W5OdL`jYcNl}O~ZLIy~ zsCEijsEO7-)1OXbj}v6|G!$3HtC`@Q9K!FzC0TWqRv1HjWo1X)>J#Rhw}@tRCorc{ z{}eF!{A_bqsyciIGNcEz7hE(zUxFGneBgohXQy&}Z_b+#A!s?v&NG3uk_X`b%JHtx9JXTp_^Hd8-KKeSh=%zO|M7YK|o zIHlIogu1?dPy=d2;crAK;pS-M^KtSAn;Z{+?ceat>`;tQFZR^Sts`3BGxFV4F>ZGJ zJ<5hIi_5zDm9ENi@U|0zL^5baGX}V_2f@ykDHvdPfG2$CS9F4hsrCyD#kgmNjt;>6 zW4!Qcf97v6bUsMkYlIV6ZVMoY0E z6)_o%bO@?e#ob&L{+(Dytr}sjaGgbmmV<|eVaR!=cQzq70Bc^jwfzwE9XrKCkQK9& zW5=H>fggT(nkiuU@)nuvB!I&U#X_#)%K_QtSd|-)_ zwTPEhg;%hQl$Q3b*tJeFY=87nU(!-1p;`=kqWO9(ClTnUXdZinq{$r56pPi8XY%4! zscy;w-~u_s)W_ZOzX{@Ejt^`=BxrZ`9>9A^h2r zj+1vQa5VYy@b4`X*mvHU;NKzm)9o=$HN?a|4)qyy94y6}hCv_KN+!r^$#jMtLMwya z0pu=z{_6T>u+p~2>8!+hION23>z7R>n;PV4uQf*P;69KJj)WF6@(AB8`}wsI3>G|e zr9~e>5S*V8gvH{01mTQ-&H~@8{zM!(VCQ-r8{qUbJYGmSb2QRXs|!E18C#DfCq=Gt zeEb=+R)MD?_TourneT9V3@Ow<;JFhBNc#gO!-v2P1*{Ra-RL}9P2c_=5kNA3GM_(F zV3~Pa``qInw#}C#;Kwad!=pFB!@fu6LR5B}PY2R?(I<}lP)pRX$+GgqdZ*LgJ2IiVo zHZe?a6uRs`!zo1-*I(^ohEHIYl6V&u(>ntnUXz%Kj z>ek}j6P2BCE%%ariUNtL9N=iuGVt!@KC~~`gtNGm9o8+|M11b2h+ETS8dxRKNpO8D z$#X#0FUkEhV+%PEYV56}aBVD|%@jdDq>VsuKzgVT`oP%I$x_)L8B5)fiaixw=;>#U zicsa3C8p54nvW*2JYb2{+WWuCg@J?YdI()4wN@l%9<)oG0(%n#Ug?WnwCbm_GyQ$y zB7j$0r+T9NU##0TuUjsDux>v_4PltUvnISF>W<160v4YZ*4!-MC&jgB-9VYNGPf>7 zqO|?#e@AxSuhGE;CdJSYsn-1gsOXax$927{Fg}ST-`XuvBJgNHSNZ0wP5>l+Iaa7L zS;O`Cew*g~nxfjSk-7G!Mu5O_hAb=>e8aQSP&dKx+3(RuxBU0U<<;-ehxdsY!b*ff zi|ucV!0|#h3%73$F>RxF_dM|!v20LakJHZ#^^ePgdU|3rL~BvD-yhLPeB?En4Tm$x{wj7+)f{k|r(v``RV^v-lr;4? z-2HrT-9!Q{qS<~s%(k#kK48)`*{GwxqhLW=DKVnyH_@(Fvql3Od$4YUaDtoOfX)Tnh zmW}L4t7PqI(cV89NmS>JbdfOMl9fU-gTA7nspy`i5szN=?|R-gHzjxsSURgFVeTtw=2wbI+zXEQP%Xd zAm{4JbuChJem?(1G*H2_-+at%Y}&E9FaWETu3J3|5n2fdf-)t2@&*xDWIYzG@_9tz zbe^y{-|oTLNBoC0@3r_(F8YYl1BOScMIq)*f6i3tCgZ`s`TEk&BzUWvm+S^p@iFM9 z(=T_oeAKPp)Kjzaxqz&_dh;mM>e6D^r!{=pM64qD2;uaUSQe!pwxUnTRR(%@Fq_cR zUtDF?oPQI#eQ{FsuK>~v1z2aOGtvwN=XcT!1=ETES?6~P5f|fQXT%ozYG*w7YFqsX zo5WhlcwqGW&Q;XWlSF&GWIi&l1M)y4$J{EecWh+CAvaCse4&l_4=%2&=h(yo16K9j zgjb}ueAO|$o@$u>G5ez$+NEE4#K3#Tx1b%cVC0D!42It?>Q-%P<+k#UE7^g>o+w1E z(%Q^VZ)pF@szNZr*D87?oZ11m_lF7%Is1(l@4#31J3X84HQO7bx}T7%mn6+=d|US9 zJA{@sg{(Gy;Z?=s{xPQM`&i`leMa_C#>w?~Wsw=C8O)N*Lw;B%5rNE+7*a5YSd0x8 z<`uK~!ONN`YdtQinR9!61A%Yj2_t;b6gUhLjKG^iNZrAf5cI&>KV=aZM|8mqrIavP zZPcvAw85wgqt75V0`PPeBx+XWDy^_F7NtT532K)IiFFg8A!S-I(JNfK@P@O+^H5>o zW#B3Y`vD_SK_xcMR@U@_5g2=&-sSV`ww<{B;|Danpf$Sl1-LEOUp}I+z5oKBpF(ME zb-HbOwHs<$cVcQ&!bYjfU57PTbjfTCTFUC+JQZ98WXjuCRNByNd!+-aTr%dW zr7XE#DO*o5Sj*CWx0s{j?%U1fjzluqUPvrAe#z6SM%^6I0`*51;V^v~I!i>IG-*Jy zDC`o^9L3)%=@!m4i=G%-BTbA&f*5>gyCpowLzQ3u|W)(X$4cgm_g%&~P6(P7bBdO3&wbryB^Ruzm zkJWTEu&X?Z<|~Ewdqj6l!*bL+`Y&~!j%4W{-%)>5o_MU4_O5zY#}D7b(^$*M@*1{T zz5!M}{as|qKGq*1%5}HuU8t2mE_b$85R)0lerp=LuQcgX#&2|8!7hgXNFn>ppExmk~>VF%+=0El1GU_~q#xj)R z@0+#-(xtT%gY95x-9yMvGkhd6XEGmRg)0bX|(bL%EB#zB*!eDm38#z za&`&euhYUopH-`^l1XQ-lTth?tDUl|sz7t~WBPb{F6E+XIdF8= zDh2*q+jmIGXNiFrMI^3u&aLGO({G#DqxJoPpX@WxJ~SNTjl-bmdr{#8CaZT*KiaTy zQU;rWev9Up)l!)3X@A?TcfrJ%{pV#KJ~Yfp3N!%Dax-2Z63 zX8uKxCFd>O`c^}IFBUqS?r|^Fe0H7u`F2H?-!nc8!wqB{)vrGws*!cDzEp3oyVlX4 zL*e~N%;mY*C2&6)K_kTnn6i2<3FH&5`fb(S_kXV5_T1g@@VoX{h!Z+|uX}AoG&sK@ zd+6`&Sj`)n_%D8<@5Y`Q#sdf%AL4&y+8o(AVKB3mRtq_w}MQz!yznB_s|;l98Bz`yRzn|}T6a)tI5km!&v(=?h|3XG^2kHSj# zN)bDC@K880;Lj0g>htf(&mt4^w&%WdZpx-;HdH=u_;Q1M^k>SM^;e3(=cQmhy%L!O zE9L7HA65u(nil)W?X6U$;<$xn3z5}k#Qh$|R$`MX5tf8KVLGN4I<+2;-iVIsO4mV0 zn^#r`a{N5+p?It?m|^-}uQ$`5@4TnI8D@}`g|e!xaXBAYU{zMIP@A9*knbiC_H^HD zHKnl>3H|jE=Vr(G3C>wcrf-#f$yg=OcPVK+(NbHe<#IAbx6u+*dl;9vSJ17kjz#~` z86eaYdGgXzRd!Lx=_odufs$J+lx(RHX1P2Jo2ia-G+1w9(aaL0_Yf-|prZ0^H_2xU z7(05azu$_VTDu?9K5lZBiaGBP*!p1ced@_3oViIYwObA!RJ)J4dF>n{bDsqw@={>Bl-R-uMKV$f`lQkf1-Lfq zwH(H#+XCz%U8UB=*(~apREC~3B*}O^HGwKwk{!lmrduxrqxeEdau@u!i#V?|8v`N1 zHRmjVi2Kp`Cj5m-hCWT z*8aWBSl%iaINakle+dD)|HC~AIuJOe@0(=wu^zrFoOe-e7`FiH(83dVaSfQbCkWL5 zhOrqZmNHR2;#TB-A>M^4EyqP?r0`W^_)_Ems{U7fCW7nJjVhxIDR@ShTY5cw z$GMLS`11rrur(lofRG;2aFA%3;PIDg{6oMn_II#9)a2te_8&p?Dni8T%com+$wLTy zDwEP1o%?fq5SN>P`-<;-(FWRr`dMFxp%&=?bRP>7?R4XhHTzk^_o$n(R*9xM#;zPM zjDp3X7RtOgW4>CfvGUlIn@O|XHLt!%j9S1G&%UhHs3kT@}nmYjW&ffF9_{1-dw`(UIm9L)_L()&v3!Ud(F$)W|`)RuVJrovND8Q6obT@F%5)c_Y7Ij6Y>W})az%yOz!GN9RmfgNc>8=Fa?{b3Q2&6&G-)yCtl@_ z&f|}C`Neu4)Z9jEusW<*S`jYp*$rmDsc`vKv4=F?(%)Ybqs@NE6Vy4ISu=&sAIBnG z4etZ9vZm`zzc**H($Du5$aK}BnbrCyVz9AT-B4DPzm8N)9%&hsf9lH2$xsnM`aJ<;jnb0r7pmmff!^BTKwc`sZFLY6 z5~)3mPG=uW^mKmUaQ12H0QL`;*Vu;DGHw#zxs%G8zoiY=#XIu3Q{hd>rR)-Ce6b@v zwxW8MQ3!!-{EsXW;G3PxUWP@@UbV6(6&4HVP1IQBwpK*38STKfUG%1H!+uWB+@_Vk zDt>qCAWYz7cTgPn6KL&q?BYn{JHfe~hE^n~WH6}C%CZ5pDbF?DWxs$R9;J#KPEf)% z-?sKsSr~N-QqGz420>=c_nIogKP4b5&)U4Qlv+(u>%hU0rpi19VKZBB$Tq5hPv@&wBs>j#2eMT8G!mBXc zR#%)nfGDks2<+b#_2%E2%S<7QBKFp`tj(e0IWn$NvY|2yBdwqk@dgYx3<>CvT}Zqs zc6hV|ODH2pc?`~8t!!LOVArrNCNXc=6tPzS&Mrh%!o&e_v41ZaFxPr zuh-=c!2_U|``h))^KcUmfc2<^uA_Cxurv%-;Cohl>Ror)1!Ukhw=G_&1?_h}``6sb|QB-In?;&P1yEj3GLCK^NV zV%6k&8Q=gX)3}s-+y7L3sKBbfTw%LM?<_45e5+ukr*0j&0Ya@yvc^5>)i*F}*@ySD z?lClTcrnW#K^`EgqAA)&Lr>~4L%|$*Bw&%|EQghogFA6%5uw~^%E@%@Lv1yig6D1~ zxqohA4Xrp|I&GQ$8RU@EySCtskmX)dNbCfjP0jxtIn{s(o!K;=`9d=%Hqps3FOY)% zceuq%L1dd2N2NMAdyOnQm%cv&Ba>nWLNPNWm^&xbH`*K{0Me0i~V(=xkY4!#Lja*Zmr59xZPLU^%0Q3 zDg9m;_KsMSgPWV0X=dK9i&iZ>lavl{LEp{tC{N1ljfj51XFlDYpUStg9@gSEpr-UJ zU7H`LK&`;rLJ;g^)!LX?{No+>?QV@J1|#uO6$lAZ6$r6X6$P#ztGyI?{(sLY^7>7_ zS}vbb3`~-Pwlhr&2Qy6zC&1;H6R}cYStkWkU{SpvmJ);bqYX&RxtZwnJ!11f)88Q- z-nfC-GtTv;7`tRaxfm^TXckV(qCB~N>Hz0onZ+7DcfgCtxTDD z7t8w?4^`l1-|*!-TbAQycj9KdS$rb$0EO5|LC>76%T?V|Mw5H~S`4}^%(cBoVzFWC z!6^&9_{8CNb}x5UYk9BeswBD;ipO%TT1_b@w-|?4Qcfnvw3>*yV+i{YC)W`Kq| zNfafkrsZML(-S95#(SwA%7^|V)x^Ynp&2sFPtX2$caa^Dmc({ezHw_Y*rCF&dIXYN zd{3Of>iCG{->3ZYh4v^XT=Muv{kUbf;XmwlgE%0r@xNj(&F)D}=nQ}Pk^87gELr0W zN(7U`t85uSF*h{OwgHIZn_K(wed|rpaobRP;j0ca<0ch)N=xj6QBt-5r4FJ~{MHRM_mK?`Ht+lfbz7_Pc zB*NEbfh0d$Mbm&@e1{m~l4~W?RJrKb4w}kAD?s@%j zIEr|ciHM7w+m8+mhGWnVMShQpK4qO);m&%5Q5@gyY4OknmXjDO|IQ-p2bl0x$ztTQ z?bd?@Z(FB=_WRLmszNj zvW#D8OeI`x<4}GG^=^2nC9jW#%Asc4IL0Oh1boWapF%K8_Y zW4zYhwV;d^T@$1umGhtG(YSE><;%+7(z+lN7w04@ED0B#M&z|YiM^FiHWax9r$^Nf zO4Rg&fAWEI4{Xo2Md8llc>E}?z~Vb6z6@a&Q%-5{8m+jL)+Q%d46Sjdmq(+i{o^xD zq1iPeR&F@MqV)uMx-eSoRPLyfEj9P3JkZwrisaGXgs48J!Fb}W9)ohOJwCout~%>K zH3;XNLN%1)8QO1768{bni0GzRD!X~<1fkye;(xGi&B=QGJ)cWq>0+ihY9-<###Q3n zb}qRWb|LpSIO{>IjN90>O0P$ou&vR3-Z^5S#o}#!$C|2(aAz-tgG+|_6n;Jf92ae-{|6L2mX#&U_ygc1-?sVE!WC{d2U#VWKcp2;W>rA`p-s>dv`VaxkIUyR)ReVqzoU+iGr-8;@0(^=oj@v+CY{y z@Hf2CHHrdlvSvRBE3c=g4_`uuY0$6Q!e6b{y2|Sh(LIt^{#MVUW>1VEy&+}d)8x*I zUum(ntd}J3e1~W>+lbu;n1@{zhip|?yK|OXyPLDtY^=by2Q|9`N4gF5tT($Kf8MaS zx~C4}52EOpk|iw`TPTxwh}5APrvOlyqLg5=n^4JBVIGPCyM6Z(QU(Di5NM3o&#NsR9`Li>5 zm{oaZAt=_<>;z%tZgvT4b_ffyQ`R=p>WXMdQ3tp9S13{dRGWtz=hTVWN!;uJlVO%{ zVI4L%TSH=oh5oZVOA95eduYFS=d4gDbEq~)gxQ)rBM2{L+R#vzKIDL@3zj@%=$JWE z7Xr`38LM^tnAtLJ((F#*h&gip88hp2QE}{WIUKS+no$v{h{l6N+U#QL8tT{%cKAxY zFWi|OV(2Dg>3#_dRs7hISN>;wVmq$0QsFPwJJ!_JAmKFBl8NnHIDsWs?;nwO>}$p8 zNE(!+nx>QpCa9MM-Z)9vcp1>h=~>Ujx1Y!p_TuADj?R0g{)%b2`R(((W2(uTzpb~J zi|6H#hx47kaz~ilIs0IN?6k2a+52FI*8MDOLs*u`=%q>SdFQ&_}N1%PN$)`6y$BJV)~G9efpv+$xm0!?B?=y-@z@<=TuS19nADTOst}q6BVoY&sR~%^ZiF~ zdB`(_a3?0s82|sk{4YEZ_yxKUJSNUqvh*Q8OwXfP-iL1{7f~$#spX@`izt*glG)aM zV)Y)Fb65{{2)6I=#j^zv_o5-&%0ime10Wci-DRJSh;ddp^xek>QD~)?Xk9etktw#C z)V_NeeMYcd3AA%*mQQ>)2FV9v@>Fl6L+l*5o^y^0OrhHFKuGg2WIwNOhNNklFgi96 zQ{W5&eal?4(33A7^-9BJNgIQi#}{P|@&G5dsM2Eoj{VtMR2F!~q-?d>Ni!*AYE~7D9%Y?%h`EwdQ?+zmC$fHf<6ZKQ^LSBnDH(UOW>BMvrST;Uw#l{QGWH z@8LmfHbQ6$Pp7*DNv|;CFzVYAI^_K)SUv<`^e_+l_bWRMd-Dk(2;y1aT&+_&Wu`S-pjh`Q!&%g4;UqvRhp-C@8dF4Fji;}WN z8*NL@S`)Lmi5zOC+_%9<)mfYhbhSF@YPTk-$kp>EPs#~<*0pRfVd?_1sV)!V!rb%9 z{1lhXGb@jekJ@rsE?)UlqInd`q_hkxUH`Yq{My|4&zNoL5CCgc!VM|P^-K0eVLf2q z@AW?G;+#}o-lko)-aI9{R@^0VGB-hoVU^3Qb^nwAK(Ku@W9Kzl~{~E7-Dk0naIe=c7+Nog215&&VkLt z!ifGeCgTraWgrs3^()&LLXeREOIAJQqBUyDH&OvSBlGkwuyz+%^5uwnh)9Z`QxZSk z)avQ~`P=l$KI62tI(%m^)R`rrT%)%kzge-iv=vJ|9Yx;W+fYiXKrtEDMCy*AK{^Ps zFTHi25C91Y^yelSjIs{7f{1%*0@*7vA>{G<9^o~b{1>L1w$C%h-)osbpqVnhXUz0- zayTL!?A~Zkw_{Lw*9obYL(ceXsPCo7C}+cX5DD6xEG~G;CaB$M6HyFT%Wex(%kCCa z%gz8|K%KuO?6;`4JympcJCqLlRDX*m&P7lHdyPdLo8xci0;bjWf`aX2-u-Zszjg|+ zkfU`GVc8IGoaYrzY4)&#z_?FxlaesB(4f!#ROg=VT^k{n0Zs?5c#Luyutp>y)=;wS z;*2XPLmByrj>;w4c*zYq*h_Ll8nwPS!R+e|w$mr~$H$5J3$tw->`pMElHJU3MHvtJ zsU69730*Z>sn8<}+AlZx`xzISW*w{h!snS(7N923-_IVXoVf)iI9jToWcG< z_bL5i*!IyM$x&WxwLg2bIqO8-smOXwzvjI_TJ#2n{xi=R?m;>$+mVS$#VaiJtSM*0 zR188l(#BJFZ%P?C1*Nf&Jb&5~2j9n3@Z|8%Tbuv3C*9Effi13R@zQMr0%>=-On6A> z9S`x@a8_=ArQ+*WO^2W(gKAzG;(65jXF$pG^f^XA9)AJ+Dg3v2iX9D1V+1fOkNWz! zlyE67wvyw;u5(gf#hw8uvCSVWJ=(!H_4k{R8}c!IEwy?Tbo#+XSVZJAi}i4$x*J)ET0s#$k{L?$}af zHpouPpl-jVqXS=y6r&Fv_B@yt1n(0MOn0z`FSLCi5O9G-=FWInYEH++sAdN9IZr_f zS~+dBEubOO;#d_{x7q6yg-=A}CF0@G=5>{wfqfsB2cEvld=1#$*U#VG&Hu>h-w!8@ zDXu%o^vn1}vqU-`Hpw*p$Dca0`{p&w1yaZpuM{3-L?$Io+9>PlQ*_JQZb316>8|Ld zB$!%Mq${+Kf{{}K1cU%j{`ZE0AJNDyT zi$Zh2?a7vnslHQs2+_&P86yvGBv-ywX5kYG#&jin`1D9oT~uL=9IRNPXl<0B6r5wj zpN;YIdw7fxs<|wmrPq}*O`}`PVkr31v_Uw}WcGMa=183^_p$Pbwq&eCXv}F#k8(`Y z_9Vf@hN09&!f{+UWK2(17jXox1|nJPF~*AzYPhovGp`TOH#Y2vmc_y4rS;JzgVv~I zq|}IMHSzEZa;L?O`2xnM%LSQYrNt!!{Q8{2B-i*-7a!Oqr$Y_yzq6d(Sl?A(5y2!2 z@kS^$X)@saJm7!Uy88NLnPt3uzDwNe;j(dM97>cl=N&TP6P1Qj8M-d1Hj8P+;Uv9g z#-xB2j?a@V#mNS7N{|_yn4FQ#4v863GU+7Y&m0(~1h7vHuBK$H4 z(zc0M*@cmIengUKY`=p^RNyI6DQTg42P@zvzmcz#hAOavcDIkW3t+_=%5#2vP=`r# z0tsX40KZ}iXBqZ2rCh$jm915rl0jI_B~0rD_Ho6KU8ZnsR*g3TEbD#Uz6=o+`hm7@ z;#dW&c$2ZR>c3>K3Qi>MB(3i#osWG1S2X-AK~FL90uU8z8k03XhbiV+wRr=t>2FhS zJD+SwSoF|S>Aw@6&RfI4?bTRq{bnlZrTh+JD7i(Ur{L^m@tZcQ8VcFnU**K~X80%$ z3g6nMo>A(ZaSu%K6UM-}VK968pRd2-3>5{xYfoKvQZtwDC0$yAK6REYw3Hi`BwRYk za341U^p#ygdcdS|H%{C=oiF$vUijp=PA1h*mp-N!Wf|6CPsm=I?Ksg}p%9(6dxPH^ zp^`WVRRhL{L`7K*9XhJSv}Rcy$O2v3hiJu9r6*;ow)lw$X9&#I|kQwrwX<=ku+pnlq$&b*?=bnfpZ(F0-*=i=Xd~2wE%~Wvuv~EJmB2W{QpHw$pd6_*KKe2T!>&It z16aSrdkM6^D|(K4cl!;RYc-HZ^T~SxdC`P&g#v0`=k-5K%XNz2+yFMvlV5ckj`THQ zs(1I7(molBK^N{Zd>qzNq;X9qhjlSEe4ufND-&LlMU@^r_q8}$r1%lq^OCay&@^a;?etnRz0%=b~>V30lUqf1#;Sq-YM^m-VW?6;575h*B z-t_{UHUF&bmD|~Vb1p4`+JTpp5h-UZPZuk(-Hwf~&6UyWPL`)(ZL$#yKOpv30?l{j zg(@dc^eC}4m5CgfNlgC8lzEk2)lw?l837{QM10EssM;H6<)H#1`M6-XNkkaOe`DVC z#NBTTa;$pzk8nZUnNU%A} z*P@h%P-TKnCED<@rSz5sIM(<`m~hX$N1CMMFLvm9@kZ35qcG#&^MioKLeT8F=^35} zRosM_y{uipc)^2N|~=wO0ldNiu&V`HzuKvetHZ@ zI~=K6r=x*_mNQ3fIZvnfMdK)+=a+sV4|8V$T&JUL83bU8CWUI*pRcC^&y z!j}ZQ*6#Q!uQ-n#YbHkFG3r>#Cf&RlA!njY!s$iwh#oeoSYqJd}nqR zaoeGW{VF&kn87mX_i6OLFqc+L^02qZNx0+ld44c8@(|ZR`hGN*_G4K# zv)RC!a>gchPE(L5Whn|sk&dGLzR|+Jnorw|IC{=z$9A^e&>X|y2%u~0?nN1`cb?Me zoo-DPoBmUOPiN>=ZDqZR5e^DROW&r8_P2TQP*pluN2uCU{kS@90J=dVqwKrtTj}TO zhEO&#pam-pB_(SS;=M4CTA_Kbqw49*6Mi+L|K>A+Cb32TNuOggTTI7? z=HH%|I{(=`BlSWFBC48|w4I|oVlDqL|fJ0;^ za*L61MnBuC+qxw2>sPTc1K(0o;Ikp^WGY3rlf1fzoX*KO7R7bx-yD@gyQsAqZYfmL zg^ZNusb)e7U>=?A;}>e7CkAg~=$?w(6qJR^G>o=NbnP%~35rym} zakC-@0~dDYlWiR#p(I?7xL=gGC96i!31W9)Z)WoBBumSMqG^%jE8BlL+}=RufTqLI z3Gr5_7$0c`e4y)220QWyIu6{`31)ANfkj-*05D=0>&_L@zt%m#ac-0l)1#T9^rdsV zRR4iEE;w-yORrxWsfyNDfChts-(J@tFB~?hyHvexNo*XdpM+IOVfy{=7jC>LqSh1B zCJgA-`1xALN;PqG8A+Y!lla!jjYSLoL3rVt_z z#lswF$SnUq>`x*-6C_K8T+2KKwVf%Hq44s`mA8W(6_gVDS!8@O%rca#+p$t1=9GRY z+Wt+PG)i+U5XGU&cWs$g9%sQ9gJ!AVrM2!aAM!@P zFy74CJ1<>45yz~QHELH=TeeT$NF>7IHC<;s*UOlYMbM3nW#-RfiZ|lw1T)Xa+y2wr z(bQ08)I&vAt6XnA*PsJSusw9DiprA+3Vp|f?ExMbez=q<#sto*^*K_VoLQqSBo15^ z_NdTh6)eaWBW|6I9}z38KO$@nJsmj+v-amBw#;e@n;1;fB{|3mJAfQyLw(9j5&cpvx;$8&uv;GcLEd})vx4w;}3-N0M zvrFe+84E;c0WdTLB#r^3I}QmNJW60B?bJ6BY^z7w^O}+x62}0+bGt0Cq$cZ$1**mwSi8(w{7!<$`2)+4 zZSt7^ZWek%mL!OW_j#51;P?HtyIV4iXYRLn1D?Y9d;*1XE2IEWh@e1bX4-?K{hf`o z!`K;F*k7K!fRT1?tp3%odp1M|SN+n7P^-@NFK-2XA5>$$TPuX0oHo(q^)5!jAD~{b zszW`OohPkT!-d+GDjTbpB2TJWY4Aw3^^Gl=jA>twyb1=>-*CaHY4F=ee5}o0m42L9 zc*Dyw*RV~rbe`lL-H&;_&=rpUpv#jj#worWSRzjy*#|aVF9#_Mj6Ozhyjcvfmvpi8 z<(7+NInLN9aZYru<97QY8;U&C#`q^W1gW2Ra1LJQUvYwXI!xxi7v_R*`h_Az-I$eZ zcW&(Rw?u9!VlcUaqrh`Dg?nH$6yrK5(9rvWMV+j?oXa0Lx~!dV=^A(w8*oTfWJBYL zjzdz_*%Q|a0dw7u4r3NcN9wipc7t%*IZx84q=TD~CQbVU&)`&f*%h_v>tx^vTVB)U ztkbzC?k*+j=W#XW_qi}4wWa-eJ5mN~&;5RXTJSNF8yky+?Du-SrNP z@R9zHE;y$dU&$ci7W5gAs`KS9zo>zS(MiQx$TbYWXM0G1pbl=2?5$_iQimw7-r8V=XXw`(|Z9m zXxik|hHC4Q`SMpGb$bn1=u&h9CiV9=?DIm1V5MMXM$vsrjF$geMb>0DGzG*cY2&=G zpLMY=apKnIj{8*1&GOLmF)}#LNOLds3-2`9K?n=ZJLq_l1d2={oz&RX$;I|i5{~^# z++r3uO1{LQ6iJ?hZog5zq-5MsgsIQtuamH(lw7WWlOoPE7tTK|fl@<(QWpzMir*RA|yh1Jzy1W|&EB615Wg%(V}FoQn3R%}Y`k?3F3p_AP`n z7CC7SR!!4ja?I?eZZ}6y>4j^g67J;e3wD(S=gK#1Fb949%~ej;17fR5@OnI$;ZPD*m%OXrfw)L7In+@?Sdj14!!bHs zI(8P{0vfK_InrKssqNeZSD!?}n7;7cGAf!v)eJY!Bs^`r@X*NY!EyGDUyXx=0*=NY z@5Em!w3wJqNn+*DRNS#xeHbv!mHC+oL(tJe-rz98MFRFr7qYb960sRT{#bKD1;}yhYcW zEI!TcTx88X@N6!-*CtmwP5<6(aFp%Vi&q|6fhdXRwylsAI}j#Y_t?Rf|0h%C5v%SN zIfag`QAcK7gkzz**+mr6mVtSl!?=W0ow20BeWNTR@!d~?FC4j&zc)!ISs+w+WA~2} z6Y*XF$ng=SmAP~l{p@j|-7F>w>1P`Vuwd&0d~r%CX*rq?@c6e0LCZLXK#( zh>`~G^SKuB(Xqk$=1v_+^5wE=+N3ONIB#Hysz;u@W9?;q^BVsZ!Dq zH8fEGtENqD)cT$-9kLsFCq@gXJbLPnC0z2BZ<(t4gth70-1|8w%7dCi$~jr&m)Gwc z^l{>+M^7{%%_q1nz49$?(*%Fs9t0Jp*zn0FXNS&?&SqA2vW1;gC(8tQn&J903ra;7 z-eGIr$kVGfjZ$`2vAO7P*jTIBv~K{pCK2NhD5eHZC6h3)i_<&Xs$av+6Kt+uLD_ed zBEMasz-`b2)AP8s9EE4IdQsJmV|=7*63McP2106W9'FJx>$hsSGbXR!~N`!a-L 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

` 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 G_yhpP2nzTB literal 0 HcmV?d00001 diff --git a/assets/rancher-monitoring/rancher-monitoring-104.1.2+up57.0.3.tgz b/assets/rancher-monitoring/rancher-monitoring-104.1.2+up57.0.3.tgz new file mode 100644 index 0000000000000000000000000000000000000000..95878e76a4d4f7f806b7e6ba239aede1f855114c GIT binary patch literal 480734 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 vtC5LITJ0Q4*V4-H-HT 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

k3+RMvUj`0+hB~Z%!eMPIHmG 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

)sb-WZ*=i&f_iy=zsNRsXT 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%0AF_Suiz! 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 R{{a91|NqXxz=Hq?Dgemy!s-A3 literal 0 HcmV?d00001 diff --git a/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/_helpers.tpl b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/_helpers.tpl new file mode 100644 index 0000000000..146bc45a14 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/_helpers.tpl @@ -0,0 +1,30 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + diff --git a/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/jobs.yaml b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/jobs.yaml new file mode 100644 index 0000000000..6955e3b309 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/jobs.yaml @@ -0,0 +1,102 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Chart.Name }}-create + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }} + annotations: + "helm.sh/hook": post-install, post-upgrade, post-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed +spec: + template: + metadata: + name: {{ .Chart.Name }}-create + labels: + app: {{ .Chart.Name }} + spec: + serviceAccountName: {{ .Chart.Name }}-manager + securityContext: + runAsNonRoot: false + runAsUser: 0 + containers: + - name: create-crds + image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - > + echo "Applying CRDs..."; + mkdir -p /etc/crd; + base64 -d /etc/config/crd-manifest.tgz.b64 | tar -xzv -C /etc/crd; + kubectl replace -Rf /etc/crd || kubectl create -Rf /etc/crd; + echo "Done!" + volumeMounts: + - name: crd-manifest + readOnly: true + mountPath: /etc/config + restartPolicy: OnFailure + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} + {{- if .Values.nodeSelector }} + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + {{- if .Values.tolerations }} + {{- toYaml .Values.tolerations | nindent 8 }} + {{- end }} + volumes: + - name: crd-manifest + configMap: + name: {{ .Chart.Name }}-manifest +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Chart.Name }}-delete + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed +spec: + template: + metadata: + name: {{ .Chart.Name }}-delete + labels: + app: {{ .Chart.Name }} + spec: + serviceAccountName: {{ .Chart.Name }}-manager + securityContext: + runAsNonRoot: false + runAsUser: 0 + containers: + - name: delete-crds + image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - > + echo "Deleting CRDs..."; + mkdir -p /etc/crd; + base64 -d /etc/config/crd-manifest.tgz.b64 | tar -xzv -C /etc/crd; + kubectl delete --ignore-not-found=true -Rf /etc/crd; + volumeMounts: + - name: crd-manifest + readOnly: true + mountPath: /etc/config + restartPolicy: OnFailure + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} + {{- if .Values.nodeSelector }} + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + {{- if .Values.tolerations }} + {{- toYaml .Values.tolerations | nindent 8 }} + {{- end }} + volumes: + - name: crd-manifest + configMap: + name: {{ .Chart.Name }}-manifest diff --git a/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/manifest.yaml b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/manifest.yaml new file mode 100644 index 0000000000..8dc9dfb447 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.2+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.2+up57.0.3/templates/rbac.yaml b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/rbac.yaml new file mode 100644 index 0000000000..a4d498b0fa --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.2+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.2+up57.0.3/templates/validate-psp-install.yaml b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.2+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.2+up57.0.3/values.yaml b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/values.yaml new file mode 100644 index 0000000000..99e63600c4 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.2+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.2+up57.0.3/.editorconfig b/charts/rancher-monitoring/104.1.2+up57.0.3/.editorconfig new file mode 100644 index 0000000000..f5ee2f4610 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/.helmignore new file mode 100644 index 0000000000..9bdbec92b4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/CHANGELOG.md b/charts/rancher-monitoring/104.1.2+up57.0.3/CHANGELOG.md new file mode 100644 index 0000000000..8178169b91 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/CONTRIBUTING.md b/charts/rancher-monitoring/104.1.2+up57.0.3/CONTRIBUTING.md new file mode 100644 index 0000000000..f6ce2a3235 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/Chart.yaml new file mode 100644 index 0000000000..e4f8481831 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3 diff --git a/charts/rancher-monitoring/104.1.2+up57.0.3/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/README.md new file mode 100644 index 0000000000..9baf58bb16 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/app-README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/app-README.md new file mode 100644 index 0000000000..3920854384 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/.helmignore new file mode 100644 index 0000000000..8cade1318f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/Chart.yaml new file mode 100644 index 0000000000..ff6bcb26aa --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/README.md new file mode 100644 index 0000000000..0ff07f297d --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/dashboards/custom-dashboard.json b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/dashboards/custom-dashboard.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/NOTES.txt b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/NOTES.txt new file mode 100644 index 0000000000..d86419fe23 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/_config.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/_config.tpl new file mode 100644 index 0000000000..19df19cd2a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/_helpers.tpl new file mode 100644 index 0000000000..68d2d815d8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/_pod.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/_pod.tpl new file mode 100644 index 0000000000..2ebf7d5f10 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/clusterrole.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/clusterrole.yaml new file mode 100644 index 0000000000..3af4b62b63 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..bda9431a2c --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/configSecret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/configSecret.yaml new file mode 100644 index 0000000000..55574b9bbc --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/configmap-dashboard-provider.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/configmap.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/configmap.yaml new file mode 100644 index 0000000000..7d7428be51 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/dashboards-json-configmap.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/deployment.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/deployment.yaml new file mode 100644 index 0000000000..46c016faa3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/extra-manifests.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/extra-manifests.yaml new file mode 100644 index 0000000000..a9bb3b6ba8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/headless-service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/headless-service.yaml new file mode 100644 index 0000000000..3028589d32 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/hpa.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/hpa.yaml new file mode 100644 index 0000000000..46bbcb49a2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/image-renderer-deployment.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/image-renderer-hpa.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/image-renderer-network-policy.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/image-renderer-service.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/image-renderer-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/ingress.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/ingress.yaml new file mode 100644 index 0000000000..b2ffd81095 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/networkpolicy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/networkpolicy.yaml new file mode 100644 index 0000000000..4cd3ed6976 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/nginx-config.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/nginx-config.yaml new file mode 100644 index 0000000000..557471f6ff --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/poddisruptionbudget.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..05251214ac --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/podsecuritypolicy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000000..973caccd57 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/pvc.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/pvc.yaml new file mode 100644 index 0000000000..c9b234305f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/role.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/role.yaml new file mode 100644 index 0000000000..469b6f4e6c --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/rolebinding.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/rolebinding.yaml new file mode 100644 index 0000000000..58f77c6b0b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/secret-env.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/secret-env.yaml new file mode 100644 index 0000000000..eb14aac707 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/secret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/secret.yaml new file mode 100644 index 0000000000..fd2ca50f4b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/service.yaml new file mode 100644 index 0000000000..e9396a15c6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/serviceaccount.yaml new file mode 100644 index 0000000000..ffca0717ae --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/servicemonitor.yaml new file mode 100644 index 0000000000..b321b1269c --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/statefulset.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/statefulset.yaml new file mode 100644 index 0000000000..49278083e8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/templates/tests/test-configmap.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/tests/test-podsecuritypolicy.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/tests/test-role.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/tests/test-rolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/tests/test-serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/grafana/templates/tests/test.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/templates/tests/test.yaml new file mode 100644 index 0000000000..83aaa185c2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/grafana/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/grafana/values.yaml new file mode 100644 index 0000000000..45e3df9325 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.4.9 + 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.5 + # 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.2+up57.0.3/charts/hardenedKubelet/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedKubelet/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/Chart.yaml new file mode 100644 index 0000000000..acd648a5b4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedKubelet/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedKubelet/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedKubelet/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/hardenedKubelet/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/hardenedKubelet/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedKubelet/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedNodeExporter/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedNodeExporter/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/Chart.yaml new file mode 100644 index 0000000000..068932bacb --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedNodeExporter/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedNodeExporter/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/hardenedNodeExporter/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/hardenedNodeExporter/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/hardenedNodeExporter/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/hardenedNodeExporter/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/k3sServer/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/k3sServer/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/Chart.yaml new file mode 100644 index 0000000000..275e02e5dc --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/k3sServer/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/k3sServer/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/k3sServer/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/k3sServer/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/k3sServer/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/k3sServer/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/k3sServer/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/k3sServer/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/k3sServer/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/k3sServer/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/k3sServer/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kube-state-metrics/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kube-state-metrics/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/Chart.yaml new file mode 100644 index 0000000000..002a6a180d --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kube-state-metrics/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/README.md new file mode 100644 index 0000000000..843be89e69 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kube-state-metrics/templates/NOTES.txt b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/crs-configmap.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/deployment.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/extra-manifests.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/kubeconfig-secret.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/networkpolicy.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/pdb.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/podsecuritypolicy.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrole.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/rbac-configmap.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/role.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/rolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/service.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-role.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kube-state-metrics/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kube-state-metrics/values.yaml new file mode 100644 index 0000000000..bc8ee28fda --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmControllerManager/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmControllerManager/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/Chart.yaml new file mode 100644 index 0000000000..ad9fba247a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmControllerManager/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmControllerManager/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmEtcd/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmEtcd/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/Chart.yaml new file mode 100644 index 0000000000..d144d3ee2a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmEtcd/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmEtcd/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmEtcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmEtcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmEtcd/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmEtcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmProxy/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmProxy/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/Chart.yaml new file mode 100644 index 0000000000..a1222c4feb --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmProxy/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmProxy/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmProxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmProxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmProxy/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmProxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmScheduler/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmScheduler/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/Chart.yaml new file mode 100644 index 0000000000..78a44159a9 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmScheduler/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmScheduler/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/kubeAdmScheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmScheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/kubeAdmScheduler/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/kubeAdmScheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/Chart.yaml new file mode 100644 index 0000000000..d067725a17 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/README.md new file mode 100644 index 0000000000..d77bb0c920 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/NOTES.txt b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/NOTES.txt new file mode 100644 index 0000000000..b7b9b99322 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/_helpers.tpl new file mode 100644 index 0000000000..edbb829b2b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/certmanager.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/certmanager.yaml new file mode 100644 index 0000000000..4e32c964c6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/configmap.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/configmap.yaml new file mode 100644 index 0000000000..17f415d970 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/deployment.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/deployment.yaml new file mode 100644 index 0000000000..a7ea3310a0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/pdb.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/pdb.yaml new file mode 100644 index 0000000000..205761a9f1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/psp.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/psp.yaml new file mode 100644 index 0000000000..fded5a7491 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-adapter/templates/secret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/secret.yaml new file mode 100644 index 0000000000..3e7e8887bd --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/service.yaml new file mode 100644 index 0000000000..ddac37cfa1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/templates/serviceaccount.yaml new file mode 100644 index 0000000000..30a169ae0e --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-adapter/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-adapter/values.yaml new file mode 100644 index 0000000000..a1445a23f1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-node-exporter/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-node-exporter/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/Chart.yaml new file mode 100644 index 0000000000..9130cbcc91 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-node-exporter/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/README.md new file mode 100644 index 0000000000..149b982267 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/NOTES.txt b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/clusterrole.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/daemonset.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/endpoints.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/extra-manifests.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/networkpolicy.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/podmonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml new file mode 100644 index 0000000000..ee5bbba4a5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if and (or .Values.global.cattle.psp.enable (and .Values.rbac.create .Values.rbac.pspEnabled)) (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: psp-{{ include "prometheus-node-exporter.fullname" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ include "prometheus-node-exporter.fullname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/psp.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/rbac-configmap.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/service.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/prometheus-node-exporter/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/prometheus-node-exporter/values.yaml new file mode 100644 index 0000000000..b9f2f7ab87 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2ControllerManager/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2ControllerManager/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/Chart.yaml new file mode 100644 index 0000000000..dbf4d0b815 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2ControllerManager/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2ControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2ControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2ControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2ControllerManager/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2ControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Etcd/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Etcd/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/Chart.yaml new file mode 100644 index 0000000000..87495a6a6b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Etcd/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Etcd/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Etcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Etcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Etcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Etcd/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Etcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2IngressNginx/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2IngressNginx/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/Chart.yaml new file mode 100644 index 0000000000..4bce6d41ea --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2IngressNginx/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2IngressNginx/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2IngressNginx/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2IngressNginx/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2IngressNginx/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2IngressNginx/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Proxy/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Proxy/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/Chart.yaml new file mode 100644 index 0000000000..0a316e05c7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Proxy/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Proxy/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Proxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Proxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Proxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Proxy/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Proxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Scheduler/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Scheduler/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/Chart.yaml new file mode 100644 index 0000000000..fa6aa5ac66 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Scheduler/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Scheduler/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rke2Scheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Scheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rke2Scheduler/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rke2Scheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeControllerManager/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeControllerManager/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/Chart.yaml new file mode 100644 index 0000000000..df00a46b66 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeControllerManager/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeControllerManager/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeEtcd/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeEtcd/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/Chart.yaml new file mode 100644 index 0000000000..96b33f0bc8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeEtcd/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeEtcd/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeEtcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeEtcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeEtcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeEtcd/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeEtcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeIngressNginx/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeIngressNginx/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/Chart.yaml new file mode 100644 index 0000000000..bc49bcefd2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeIngressNginx/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeIngressNginx/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeIngressNginx/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeIngressNginx/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeIngressNginx/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeIngressNginx/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeProxy/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeProxy/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/Chart.yaml new file mode 100644 index 0000000000..18eac324d4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeProxy/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeProxy/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeProxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeProxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeProxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeProxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeProxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeProxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeProxy/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeProxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeScheduler/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeScheduler/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/Chart.yaml new file mode 100644 index 0000000000..8c53b63bcc --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeScheduler/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeScheduler/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeScheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/rkeScheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeScheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/charts/rkeScheduler/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/rkeScheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/.helmignore b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/Chart.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/Chart.yaml new file mode 100644 index 0000000000..784bb0ec7e --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/README.md b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/README.md new file mode 100644 index 0000000000..1da1c64e12 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/scripts/configure-firewall.ps1 b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/scripts/configure-firewall.ps1 new file mode 100644 index 0000000000..9cbed7112d --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/_helpers.tpl new file mode 100644 index 0000000000..c9a5d6db8c --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/templates/config.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/config.yaml new file mode 100644 index 0000000000..25f1fa69c2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/templates/daemonset.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/daemonset.yaml new file mode 100644 index 0000000000..be7feb3ed1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/templates/podmonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/podmonitor.yaml new file mode 100644 index 0000000000..bbb6c39340 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/templates/scriptConfig.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/scriptConfig.yaml new file mode 100644 index 0000000000..f514c8161a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/templates/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/service.yaml new file mode 100644 index 0000000000..267b796f63 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/templates/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/serviceaccount.yaml new file mode 100644 index 0000000000..14c1c46807 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/templates/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/templates/servicemonitor.yaml new file mode 100644 index 0000000000..2effc07758 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/charts/windowsExporter/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/charts/windowsExporter/values.yaml new file mode 100644 index 0000000000..04569505d6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/ingress-nginx/nginx.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/ingress-nginx/nginx.json new file mode 100644 index 0000000000..565352235a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/ingress-nginx/request-handling-performance.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/cluster/rancher-cluster-nodes.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/cluster/rancher-cluster.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/cluster/rancher-cluster.json new file mode 100644 index 0000000000..24385a237a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/fleet/bundle.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/bundle.json new file mode 100644 index 0000000000..698f48aeed --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/fleet/bundledeployment.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/bundledeployment.json new file mode 100644 index 0000000000..c81f7a6212 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/fleet/cluster.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/cluster.json new file mode 100644 index 0000000000..73bdea4834 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/fleet/clustergroup.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/clustergroup.json new file mode 100644 index 0000000000..ce3df87b21 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/fleet/controller-runtime.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/controller-runtime.json new file mode 100644 index 0000000000..23a81f2a8c --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/fleet/gitrepo.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/fleet/gitrepo.json new file mode 100644 index 0000000000..1a50c2937d --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/home/rancher-default-home.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/k8s/rancher-etcd-nodes.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/k8s/rancher-etcd.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/k8s/rancher-etcd.json new file mode 100644 index 0000000000..0c058cafb9 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/k8s/rancher-k8s-components-nodes.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/k8s/rancher-k8s-components.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/nodes/rancher-node-detail.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/nodes/rancher-node.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/nodes/rancher-node.json new file mode 100644 index 0000000000..367df3cc9d --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/performance/performance-debugging.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/performance/performance-debugging.json new file mode 100644 index 0000000000..454bc39390 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/pods/rancher-pod-containers.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/pods/rancher-pod.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/pods/rancher-pod.json new file mode 100644 index 0000000000..4859eccc74 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/rancher/workloads/rancher-workload-pods.json b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/files/rancher/workloads/rancher-workload.json b/charts/rancher-monitoring/104.1.2+up57.0.3/files/rancher/workloads/rancher-workload.json new file mode 100644 index 0000000000..9f5317c2f0 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/files/upgrade/scripts/delete-workloads-with-old-labels.sh b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/NOTES.txt b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/NOTES.txt new file mode 100644 index 0000000000..371f3ae398 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/_helpers.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/_helpers.tpl new file mode 100644 index 0000000000..d2207dd90d --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/alertmanager.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/alertmanager.yaml new file mode 100644 index 0000000000..19044054ac --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/extrasecret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/extrasecret.yaml new file mode 100644 index 0000000000..ecd8f47021 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/ingress.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/ingress.yaml new file mode 100644 index 0000000000..be9f5aa279 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/ingressperreplica.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/ingressperreplica.yaml new file mode 100644 index 0000000000..b2e00a4162 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/podDisruptionBudget.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/podDisruptionBudget.yaml new file mode 100644 index 0000000000..b183403125 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/psp-role.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/psp-role.yaml new file mode 100644 index 0000000000..8810e93ded --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/psp-rolebinding.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/psp-rolebinding.yaml new file mode 100644 index 0000000000..794f4ad178 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/psp.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/psp.yaml new file mode 100644 index 0000000000..07b616b5cb --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/secret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/secret.yaml new file mode 100644 index 0000000000..d2fe84a7bf --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/service.yaml new file mode 100644 index 0000000000..373de328a5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/serviceaccount.yaml new file mode 100644 index 0000000000..745ced8bde --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/servicemonitor.yaml new file mode 100644 index 0000000000..6233690019 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/alertmanager/serviceperreplica.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/alertmanager/serviceperreplica.yaml new file mode 100644 index 0000000000..75a13bdf97 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/core-dns/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/core-dns/service.yaml new file mode 100644 index 0000000000..b8618f7558 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/core-dns/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/core-dns/servicemonitor.yaml new file mode 100644 index 0000000000..dc15a06937 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-api-server/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/exporters/kube-controller-manager/endpoints.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/exporters/kube-controller-manager/service.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/exporters/kube-controller-manager/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/exporters/kube-dns/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-dns/service.yaml new file mode 100644 index 0000000000..81b2c9930c --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-dns/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-dns/servicemonitor.yaml new file mode 100644 index 0000000000..9fa41b575f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-etcd/endpoints.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-etcd/endpoints.yaml new file mode 100644 index 0000000000..e366447577 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-etcd/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-etcd/service.yaml new file mode 100644 index 0000000000..d07d4f35e3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-etcd/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-etcd/servicemonitor.yaml new file mode 100644 index 0000000000..26fdbdbed3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-proxy/endpoints.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-proxy/endpoints.yaml new file mode 100644 index 0000000000..8613e62425 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-proxy/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-proxy/service.yaml new file mode 100644 index 0000000000..8ccb2210d7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-proxy/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-proxy/servicemonitor.yaml new file mode 100644 index 0000000000..24b0ab2001 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-scheduler/endpoints.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-scheduler/endpoints.yaml new file mode 100644 index 0000000000..6236b42f10 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-scheduler/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-scheduler/service.yaml new file mode 100644 index 0000000000..90b3a800a4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-scheduler/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kube-scheduler/servicemonitor.yaml new file mode 100644 index 0000000000..b17c4f1d47 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/kube-state-metrics/validate.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/exporters/kubelet/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/kubelet/servicemonitor.yaml new file mode 100644 index 0000000000..f570fbfdbc --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/exporters/node-exporter/validate.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/exporters/node-exporter/validate.yaml new file mode 100644 index 0000000000..bdc73d6165 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/extra-objects.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/extra-objects.yaml new file mode 100644 index 0000000000..567f7bf329 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/grafana/configmap-dashboards.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/configmap-dashboards.yaml new file mode 100644 index 0000000000..e719009ffe --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/grafana/configmaps-datasources.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/configmaps-datasources.yaml new file mode 100644 index 0000000000..718020d4f6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/alertmanager-overview.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/apiserver.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/cluster-total.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/controller-manager.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/etcd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/grafana-overview.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-coredns.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-node.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/kubelet.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-pod.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/namespace-by-workload.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/node-rsrc-use.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/nodes-darwin.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/nodes.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/pod-total.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/prometheus.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/proxy.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/scheduler.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/dashboards-1.14/workload-total.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/grafana/namespaces.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/grafana/namespaces.yaml new file mode 100644 index 0000000000..39ed210ed4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/_prometheus-operator.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/_prometheus-operator.tpl new file mode 100644 index 0000000000..6ae9dc72e6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/service.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus-operator/certmanager.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/certmanager.yaml new file mode 100644 index 0000000000..cb27e49f48 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000000..07e2e99967 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/clusterrole.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/clusterrole.yaml new file mode 100644 index 0000000000..fd11b69eed --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/clusterrolebinding.yaml new file mode 100644 index 0000000000..ad9e3ef6c5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/deployment.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/deployment.yaml new file mode 100644 index 0000000000..8a01b2912a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/networkpolicy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/networkpolicy.yaml new file mode 100644 index 0000000000..cfd5b0b8c7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/psp-clusterrole.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/psp-clusterrole.yaml new file mode 100644 index 0000000000..61bc3d9040 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..40e0fc5c15 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/psp.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/psp.yaml new file mode 100644 index 0000000000..28a9075d3e --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/service.yaml new file mode 100644 index 0000000000..d45ab22d08 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/serviceaccount.yaml new file mode 100644 index 0000000000..4f84974f9b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/servicemonitor.yaml new file mode 100644 index 0000000000..cbe79e1253 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus-operator/verticalpodautoscaler.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus-operator/verticalpodautoscaler.yaml new file mode 100644 index 0000000000..f225d16dde --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/_rules.tpl b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/_rules.tpl new file mode 100644 index 0000000000..4a8213d089 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/additionalAlertRelabelConfigs.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/additionalAlertRelabelConfigs.yaml new file mode 100644 index 0000000000..bff930981a --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/additionalAlertmanagerConfigs.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/additionalAlertmanagerConfigs.yaml new file mode 100644 index 0000000000..2fe8fdb816 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/additionalPrometheusRules.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/additionalPrometheusRules.yaml new file mode 100644 index 0000000000..cb4aabaa7b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/additionalScrapeConfigs.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/additionalScrapeConfigs.yaml new file mode 100644 index 0000000000..ebdf766fde --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000000..74d61d7c13 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/clusterrole.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/clusterrole.yaml new file mode 100644 index 0000000000..3585b5db11 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/clusterrolebinding.yaml new file mode 100644 index 0000000000..9fc4f65da4 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/csi-secret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/csi-secret.yaml new file mode 100644 index 0000000000..e05382f633 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/extrasecret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/extrasecret.yaml new file mode 100644 index 0000000000..17f3478a46 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/ingress.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/ingress.yaml new file mode 100644 index 0000000000..d2f6af5dd1 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/ingressThanosSidecar.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/ingressThanosSidecar.yaml new file mode 100644 index 0000000000..3f507cfa9f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/ingressperreplica.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/ingressperreplica.yaml new file mode 100644 index 0000000000..1d76d135c8 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/networkpolicy.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/networkpolicy.yaml new file mode 100644 index 0000000000..1296a79063 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/nginx-config.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/nginx-config.yaml new file mode 100644 index 0000000000..e4d91f9a9e --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/podDisruptionBudget.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/podDisruptionBudget.yaml new file mode 100644 index 0000000000..48f3f1f5a6 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/podmonitors.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/podmonitors.yaml new file mode 100644 index 0000000000..4e748c23b5 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/prometheus.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/prometheus.yaml new file mode 100644 index 0000000000..5c3c8d4d1f --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/psp-clusterrole.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/psp-clusterrole.yaml new file mode 100644 index 0000000000..71476cd18b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..a393928c78 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/psp.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/psp.yaml new file mode 100644 index 0000000000..62d3854151 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/rules-1.14/alertmanager.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/config-reloaders.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/etcd.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/general.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/k8s.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kube-state-metrics.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubelet.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-apps.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-resources.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-storage.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/kubernetes-system.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/node-exporter.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/node-exporter.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/node-network.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/node.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/prometheus-operator.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/prometheus.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/windows.node.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/rules-1.14/windows.pod.rules.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/prometheus/secret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/secret.yaml new file mode 100644 index 0000000000..e4a1e73c7b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/service.yaml new file mode 100644 index 0000000000..d61b9d6ef3 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/serviceThanosSidecar.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/serviceThanosSidecar.yaml new file mode 100644 index 0000000000..15b89c8c23 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/serviceThanosSidecarExternal.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/serviceThanosSidecarExternal.yaml new file mode 100644 index 0000000000..453eed7f1b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/serviceaccount.yaml new file mode 100644 index 0000000000..e97b989bbd --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/servicemonitor.yaml new file mode 100644 index 0000000000..a36f3e33ca --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/servicemonitorThanosSidecar.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/servicemonitorThanosSidecar.yaml new file mode 100644 index 0000000000..0f70aabb58 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/servicemonitors.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/servicemonitors.yaml new file mode 100644 index 0000000000..a7a301babc --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/prometheus/serviceperreplica.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/prometheus/serviceperreplica.yaml new file mode 100644 index 0000000000..4bc7f7b869 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/rancher-monitoring/clusterrole.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/clusterrole.yaml new file mode 100644 index 0000000000..56ca9f5eae --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/rancher-monitoring/config-role.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/config-role.yaml new file mode 100644 index 0000000000..f48ffc827e --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/rancher-monitoring/dashboard-role.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/dashboard-role.yaml new file mode 100644 index 0000000000..d2f81976a2 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+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.2+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.2+up57.0.3/templates/rancher-monitoring/hardened.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/hardened.yaml new file mode 100644 index 0000000000..f9a66151ee --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/rancher-monitoring/upgrade/configmap.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/upgrade/configmap.yaml new file mode 100644 index 0000000000..53cb898214 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/rancher-monitoring/upgrade/job.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/upgrade/job.yaml new file mode 100644 index 0000000000..8f2771740c --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/rancher-monitoring/upgrade/rbac.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/rancher-monitoring/upgrade/rbac.yaml new file mode 100644 index 0000000000..e929a19925 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/thanos-ruler/extrasecret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/extrasecret.yaml new file mode 100644 index 0000000000..587fca2dca --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/thanos-ruler/ingress.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/ingress.yaml new file mode 100644 index 0000000000..e245ad448e --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/thanos-ruler/podDisruptionBudget.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/podDisruptionBudget.yaml new file mode 100644 index 0000000000..83e54edf9b --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/thanos-ruler/ruler.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/ruler.yaml new file mode 100644 index 0000000000..b281221563 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/thanos-ruler/secret.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/secret.yaml new file mode 100644 index 0000000000..acab7fd9ae --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/thanos-ruler/service.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/service.yaml new file mode 100644 index 0000000000..be0c844591 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/thanos-ruler/serviceaccount.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/serviceaccount.yaml new file mode 100644 index 0000000000..b58f1cd4df --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/thanos-ruler/servicemonitor.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/thanos-ruler/servicemonitor.yaml new file mode 100644 index 0000000000..b2b138b498 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/validate-install-crd.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..6fcb8b3a69 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/templates/validate-psp-install.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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.2+up57.0.3/values.yaml b/charts/rancher-monitoring/104.1.2+up57.0.3/values.yaml new file mode 100644 index 0000000000..d94624954d --- /dev/null +++ b/charts/rancher-monitoring/104.1.2+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: v1.4.3 + 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

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 R{~rJV|Nlr;*AoDYM*yKJNM`^5 literal 0 HcmV?d00001 diff --git a/charts/rancher-logging-crd/104.1.2+up4.8.0/Chart.yaml b/charts/rancher-logging-crd/104.1.2+up4.8.0/Chart.yaml new file mode 100644 index 0000000000..69aa3d8ff2 --- /dev/null +++ b/charts/rancher-logging-crd/104.1.2+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.2+up4.8.0 diff --git a/charts/rancher-logging-crd/104.1.2+up4.8.0/README.md b/charts/rancher-logging-crd/104.1.2+up4.8.0/README.md new file mode 100644 index 0000000000..d4beb54faf --- /dev/null +++ b/charts/rancher-logging-crd/104.1.2+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.2+up4.8.0/templates/logging-extensions.banzaicloud.io_eventtailers.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging-extensions.banzaicloud.io_hosttailers.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_clusterflows.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_clusteroutputs.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_flows.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_fluentbitagents.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_fluentdconfigs.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_loggingroutes.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_loggings.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_nodeagents.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_outputs.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_syslogngclusterflows.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_syslogngclusteroutputs.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_syslogngconfigs.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_syslogngflows.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/templates/logging.banzaicloud.io_syslogngoutputs.yaml b/charts/rancher-logging-crd/104.1.2+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.2+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.2+up4.8.0/.helmignore b/charts/rancher-logging/104.1.2+up4.8.0/.helmignore new file mode 100644 index 0000000000..b3123b9ea0 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/Chart.yaml b/charts/rancher-logging/104.1.2+up4.8.0/Chart.yaml new file mode 100644 index 0000000000..3df5a385bb --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0 diff --git a/charts/rancher-logging/104.1.2+up4.8.0/README.md b/charts/rancher-logging/104.1.2+up4.8.0/README.md new file mode 100644 index 0000000000..7f66f42ab6 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/app-readme.md b/charts/rancher-logging/104.1.2+up4.8.0/app-readme.md new file mode 100644 index 0000000000..994c597ee5 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/NOTES.txt b/charts/rancher-logging/104.1.2+up4.8.0/templates/NOTES.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/charts/rancher-logging/104.1.2+up4.8.0/templates/_generic_fluentbitagent.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/_generic_fluentbitagent.yaml new file mode 100644 index 0000000000..64dd0131d4 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/_generic_logging.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/_generic_logging.yaml new file mode 100644 index 0000000000..a143cdd9b8 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/_helpers.tpl b/charts/rancher-logging/104.1.2+up4.8.0/templates/_helpers.tpl new file mode 100644 index 0000000000..43b6a5413f --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/clusterrole.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/clusterrole.yaml new file mode 100644 index 0000000000..1e2652a7ec --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/clusterrolebinding.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..89d17d094f --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/crds.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/crds.yaml new file mode 100644 index 0000000000..f573652d04 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/deployment.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/deployment.yaml new file mode 100644 index 0000000000..0cdf494e97 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/extra-manifests.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/extra-manifests.yaml new file mode 100644 index 0000000000..567f7bf329 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/logging/clusterflows.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/logging/clusterflows.yaml new file mode 100644 index 0000000000..3a1a46bee5 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/logging/clusteroutputs.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/logging/clusteroutputs.yaml new file mode 100644 index 0000000000..60d9f30ae7 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/logging/eventtailer.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/logging/eventtailer.yaml new file mode 100644 index 0000000000..830cf9b15d --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/logging/fluentbit.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/logging/fluentbit.yaml new file mode 100644 index 0000000000..ad9bdcb319 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/logging/hosttailer.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/logging/hosttailer.yaml new file mode 100644 index 0000000000..a14d7c10b7 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/logging/logging.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/logging/logging.yaml new file mode 100644 index 0000000000..0adf992bfc --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/aks/fluentbitagent.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/aks/fluentbitagent.yaml new file mode 100644 index 0000000000..1663bc0f4b --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/aks/logging.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/aks/logging.yaml new file mode 100644 index 0000000000..6341387a68 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/eks/fluentbitagent.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/eks/fluentbitagent.yaml new file mode 100644 index 0000000000..10d49bb582 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/eks/logging.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/eks/logging.yaml new file mode 100644 index 0000000000..5d396bd696 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/gke/fluentbitagent.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/gke/fluentbitagent.yaml new file mode 100644 index 0000000000..c54d50c703 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/gke/logging.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/gke/logging.yaml new file mode 100644 index 0000000000..3271599b95 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/k3s/configmap.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/k3s/configmap.yaml new file mode 100644 index 0000000000..aa454c8adf --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/k3s/daemonset.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/k3s/daemonset.yaml new file mode 100644 index 0000000000..e80c2b1c8b --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/k3s/fluentbitagent.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/k3s/fluentbitagent.yaml new file mode 100644 index 0000000000..9b3c08a0f2 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/k3s/logging-k3s-openrc.yaml b/charts/rancher-logging/104.1.2+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.2+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.2+up4.8.0/templates/loggings/kube-audit/fluentbitagent.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/kube-audit/fluentbitagent.yaml new file mode 100644 index 0000000000..92f006b98d --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/kube-audit/logging.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/kube-audit/logging.yaml new file mode 100644 index 0000000000..1e063b9e6e --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/rke/configmap.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/rke/configmap.yaml new file mode 100644 index 0000000000..252572a4ef --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/rke/daemonset.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/rke/daemonset.yaml new file mode 100644 index 0000000000..cc39a5cc49 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/rke2/configmap.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/rke2/configmap.yaml new file mode 100644 index 0000000000..3ca20be226 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/rke2/daemonset.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/rke2/daemonset.yaml new file mode 100644 index 0000000000..8f54b718ee --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/root/fluentbitagent.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/root/fluentbitagent.yaml new file mode 100644 index 0000000000..2816b7f911 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/loggings/root/logging.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/loggings/root/logging.yaml new file mode 100644 index 0000000000..e225815e1c --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/service.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/service.yaml new file mode 100644 index 0000000000..f419ae2c48 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/service_monitor.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/service_monitor.yaml new file mode 100644 index 0000000000..fcd86b07a9 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/serviceaccount.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/serviceaccount.yaml new file mode 100644 index 0000000000..bb97cf1084 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/test_receiver.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/test_receiver.yaml new file mode 100644 index 0000000000..af0b5f4dcc --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/userrole.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/userrole.yaml new file mode 100644 index 0000000000..82c3200b9c --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/userroles.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/userroles.yaml new file mode 100644 index 0000000000..f4136b09a4 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/validate-install-crd.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..5184c85c47 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/validate-install.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/validate-install.yaml new file mode 100644 index 0000000000..bd624cc4b4 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/templates/validate-psp-install.yaml b/charts/rancher-logging/104.1.2+up4.8.0/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/values-logging-example.yaml b/charts/rancher-logging/104.1.2+up4.8.0/values-logging-example.yaml new file mode 100644 index 0000000000..b7068af4a0 --- /dev/null +++ b/charts/rancher-logging/104.1.2+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.2+up4.8.0/values.yaml b/charts/rancher-logging/104.1.2+up4.8.0/values.yaml new file mode 100644 index 0000000000..525181c54c --- /dev/null +++ b/charts/rancher-logging/104.1.2+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-kube-logging-config-reloader + tag: v0.0.5 + fluentbit: + repository: rancher/mirrored-fluent-fluent-bit + tag: 3.0.4 + nodeagent_fluentbit: + os: "windows" + repository: rancher/fluent-bit + tag: 2.2.0 + fluentbit_debug: + repository: rancher/mirrored-fluent-fluent-bit + tag: 3.0.4-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.2+up57.0.3/Chart.yaml b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/Chart.yaml new file mode 100644 index 0000000000..e5e2a88357 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.2+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.2+up57.0.3 diff --git a/charts/rancher-monitoring-crd/104.1.2+up57.0.3/README.md b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/README.md new file mode 100644 index 0000000000..e0b63e0268 --- /dev/null +++ b/charts/rancher-monitoring-crd/104.1.2+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.2+up57.0.3/files/crd-manifest.tgz b/charts/rancher-monitoring-crd/104.1.2+up57.0.3/files/crd-manifest.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4b57af9438f15e755197ada98bb369cc8644a05d GIT binary patch literal 308570 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 dFc}T)5i! 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