From 571f1d9df9693385bef7c9dc314bfe84f4167d8d Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Fri, 13 Mar 2020 02:19:58 +0800 Subject: [PATCH 01/15] Refactor Feast Helm charts 1. Use --spring.config.additional-location to specify Spring application config so the default application.yaml bundled in the jar can be used, and users only need to override required config. This is to prevent chart users being overwhelmed by the amount of config to set. 2. Use less templating, if else, and functions in configmap.yaml in Feast charts. Instead set a reasonable default and allow users to override in application-override.yaml. This makes it easier to manage when application.yaml structure changes and documentation for application.yaml can be delegated to: https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml 3. Remove double nesting of charts. Previously, Postgresql and Kafka subcharts are bundled in Feast Core suchart. Now all 3 subcharts are sibling charts. This reduces coupling between charts and it's easier to configure chart values one at a time than one big values yaml. Also, documentation for third party subcharts can be delegated to the original authors. 4. Use helm-docs to generate README for Feast charts so the documentation is reproducible and easier to keep up to date when values.yaml changes. It is also easier to follow best practices when writing values.yaml. https://github.com/norwoodj/helm-docs 5. Add prometheus and grafana charts to support out of the box metrics collector and visualization when users install Feast with this chart. 6. Add tests for users to verify installation: 7. Add examples to install Feast with 3 different profiles: - online serving only with direct runner - online and batch serving with DirectRunner - online and batch serving with DataflowRunner --- infra/charts/feast/.helmdocsignore | 6 + infra/charts/feast/Chart.yaml | 4 +- infra/charts/feast/README.md | 583 ++++--- infra/charts/feast/README.md.gotmpl | 365 ++++ .../charts/feast/charts/feast-core/Chart.yaml | 4 +- .../charts/feast/charts/feast-core/README.md | 65 + .../charts/feast-core/charts/kafka-0.20.1.tgz | Bin 30761 -> 0 bytes .../feast-core/charts/postgresql-6.5.5.tgz | Bin 23599 -> 0 bytes .../prometheus-statsd-exporter/README.md | 56 - .../feast/charts/feast-core/requirements.yaml | 15 - .../feast-core/templates/configmap.yaml | 39 +- .../feast-core/templates/deployment.yaml | 55 +- .../feast/charts/feast-core/values.yaml | 244 +-- .../feast/charts/feast-serving/Chart.yaml | 4 +- .../feast/charts/feast-serving/README.md | 65 + .../feast-serving/charts/redis-9.5.0.tgz | Bin 27574 -> 0 bytes .../charts/feast-serving/requirements.yaml | 8 - .../feast-serving/templates/configmap.yaml | 55 +- .../feast-serving/templates/deployment.yaml | 41 +- .../feast/charts/feast-serving/values.yaml | 232 +-- infra/charts/feast/charts/grafana/.helmignore | 23 + infra/charts/feast/charts/grafana/Chart.yaml | 19 + infra/charts/feast/charts/grafana/OWNERS | 8 + infra/charts/feast/charts/grafana/README.md | 128 ++ .../charts/grafana/ci/default-values.yaml | 1 + .../ci/with-dashboard-json-values.yaml | 53 + .../grafana/ci/with-dashboard-values.yaml | 19 + .../grafana/dashboards/custom-dashboard.json | 1 + .../feast/charts/grafana/templates/NOTES.txt | 53 + .../charts/grafana/templates/_helpers.tpl | 82 + .../feast/charts/grafana/templates/_pod.tpl | 369 ++++ .../charts/grafana/templates/clusterrole.yaml | 25 + .../grafana/templates/clusterrolebinding.yaml | 20 + .../configmap-dashboard-provider.yaml | 25 + .../charts/grafana/templates/configmap.yaml | 69 + .../templates/dashboards-json-configmap.yaml | 35 + .../charts/grafana/templates/deployment.yaml | 44 + .../grafana/templates/headless-service.yaml | 18 + .../charts/grafana/templates/ingress.yaml | 42 + .../templates/poddisruptionbudget.yaml | 22 + .../grafana/templates/podsecuritypolicy.yaml | 52 + .../feast/charts/grafana/templates/pvc.yaml | 28 + .../feast/charts/grafana/templates/role.yaml | 32 + .../charts/grafana/templates/rolebinding.yaml | 27 + .../charts/grafana/templates/secret-env.yaml | 14 + .../charts/grafana/templates/secret.yaml | 20 + .../charts/grafana/templates/service.yaml | 46 + .../grafana/templates/serviceaccount.yaml | 13 + .../charts/grafana/templates/statefulset.yaml | 44 + .../templates/tests/test-configmap.yaml | 17 + .../tests/test-podsecuritypolicy.yaml | 29 + .../grafana/templates/tests/test-role.yaml | 14 + .../templates/tests/test-rolebinding.yaml | 17 + .../templates/tests/test-serviceaccount.yaml | 9 + .../charts/grafana/templates/tests/test.yaml | 47 + infra/charts/feast/charts/grafana/values.yaml | 485 ++++++ .../charts/{feast-core => kafka}/.helmignore | 1 - infra/charts/feast/charts/kafka/Chart.yaml | 24 + infra/charts/feast/charts/kafka/OWNERS | 4 + infra/charts/feast/charts/kafka/README.md | 114 ++ .../charts/kafka/charts/zookeeper-2.1.0.tgz | Bin 0 -> 10646 bytes .../feast/charts/kafka/requirements.lock | 6 + .../feast/charts/kafka/requirements.yaml | 5 + .../feast/charts/kafka/templates/NOTES.txt | 76 + .../feast/charts/kafka/templates/_helpers.tpl | 128 ++ .../kafka/templates/configmap-config.yaml | 58 + .../charts/kafka/templates/configmap-jmx.yaml | 64 + .../templates/deployment-kafka-exporter.yaml | 45 + .../charts/kafka/templates/job-config.yaml | 29 + .../kafka/templates/podisruptionbudget.yaml | 14 + .../kafka/templates/prometheusrules.yaml | 16 + .../templates/service-brokers-external.yaml | 74 + .../kafka/templates/service-brokers.yaml | 36 + .../kafka/templates/service-headless.yaml | 21 + .../kafka/templates/servicemonitors.yaml | 47 + .../charts/kafka/templates/statefulset.yaml | 272 +++ .../test_topic_create_consume_produce.yaml | 24 + infra/charts/feast/charts/kafka/values.yaml | 503 ++++++ .../feast/charts/postgresql/.helmignore | 2 + .../charts/feast/charts/postgresql/Chart.yaml | 22 + infra/charts/feast/charts/postgresql/OWNERS | 18 + .../charts/feast/charts/postgresql/README.md | 134 ++ .../charts/postgresql/ci/default-values.yaml | 1 + .../ci/shmvolume-disabled-values.yaml | 2 + .../feast/charts/postgresql/files/README.md | 1 + .../charts/postgresql/files/conf.d/README.md | 4 + .../docker-entrypoint-initdb.d/README.md | 3 + .../charts/postgresql/templates/NOTES.txt | 60 + .../charts/postgresql/templates/_helpers.tpl | 420 +++++ .../postgresql/templates/configmap.yaml | 26 + .../templates/extended-config-configmap.yaml | 21 + .../templates/initialization-configmap.yaml | 24 + .../templates/metrics-configmap.yaml | 13 + .../postgresql/templates/metrics-svc.yaml | 26 + .../postgresql/templates/networkpolicy.yaml | 38 + .../postgresql/templates/prometheusrule.yaml | 23 + .../charts/postgresql/templates/secrets.yaml | 23 + .../postgresql/templates/serviceaccount.yaml | 11 + .../postgresql/templates/servicemonitor.yaml | 33 + .../templates/statefulset-slaves.yaml | 299 ++++ .../postgresql/templates/statefulset.yaml | 458 +++++ .../postgresql/templates/svc-headless.yaml | 19 + .../charts/postgresql/templates/svc-read.yaml | 31 + .../charts/postgresql/templates/svc.yaml | 38 + .../charts/postgresql/values-production.yaml | 520 ++++++ .../charts/postgresql/values.schema.json | 103 ++ .../feast/charts/postgresql/values.yaml | 526 ++++++ .../prometheus-statsd-exporter/.helmignore | 0 .../prometheus-statsd-exporter/Chart.yaml | 0 .../prometheus-statsd-exporter/README.md | 49 + .../templates/NOTES.txt | 0 .../templates/_helpers.tpl | 0 .../templates/config.yaml | 0 .../templates/deployment.yaml | 2 +- .../templates/pvc.yaml | 0 .../templates/service.yaml | 40 +- .../templates/serviceaccount.yaml | 0 .../prometheus-statsd-exporter/values.yaml | 3 + .../{feast-serving => prometheus}/.helmignore | 3 +- .../charts/feast/charts/prometheus/Chart.yaml | 20 + infra/charts/feast/charts/prometheus/OWNERS | 6 + .../charts/feast/charts/prometheus/README.md | 448 +++++ .../feast/charts/prometheus/requirements.yaml | 7 + .../charts/prometheus/templates/NOTES.txt | 112 ++ .../charts/prometheus/templates/_helpers.tpl | 276 +++ .../templates/alertmanager-clusterrole.yaml | 21 + .../alertmanager-clusterrolebinding.yaml | 16 + .../templates/alertmanager-configmap.yaml | 18 + .../templates/alertmanager-deployment.yaml | 142 ++ .../templates/alertmanager-ingress.yaml | 42 + .../templates/alertmanager-networkpolicy.yaml | 19 + .../templates/alertmanager-pdb.yaml | 13 + .../alertmanager-podsecuritypolicy.yaml | 48 + .../templates/alertmanager-pvc.yaml | 32 + .../alertmanager-service-headless.yaml | 30 + .../templates/alertmanager-service.yaml | 52 + .../alertmanager-serviceaccount.yaml | 8 + .../templates/alertmanager-statefulset.yaml | 152 ++ .../templates/node-exporter-daemonset.yaml | 116 ++ .../node-exporter-podsecuritypolicy.yaml | 55 + .../templates/node-exporter-role.yaml | 17 + .../templates/node-exporter-rolebinding.yaml | 19 + .../templates/node-exporter-service.yaml | 40 + .../node-exporter-serviceaccount.yaml | 8 + .../templates/pushgateway-clusterrole.yaml | 21 + .../pushgateway-clusterrolebinding.yaml | 16 + .../templates/pushgateway-deployment.yaml | 100 ++ .../templates/pushgateway-ingress.yaml | 39 + .../templates/pushgateway-networkpolicy.yaml | 19 + .../prometheus/templates/pushgateway-pdb.yaml | 13 + .../pushgateway-podsecuritypolicy.yaml | 44 + .../prometheus/templates/pushgateway-pvc.yaml | 30 + .../templates/pushgateway-service.yaml | 40 + .../templates/pushgateway-serviceaccount.yaml | 8 + .../templates/server-clusterrole.yaml | 47 + .../templates/server-clusterrolebinding.yaml | 16 + .../templates/server-configmap.yaml | 81 + .../templates/server-deployment.yaml | 217 +++ .../prometheus/templates/server-ingress.yaml | 44 + .../templates/server-networkpolicy.yaml | 17 + .../prometheus/templates/server-pdb.yaml | 13 + .../templates/server-podsecuritypolicy.yaml | 53 + .../prometheus/templates/server-pvc.yaml | 34 + .../templates/server-service-headless.yaml | 26 + .../prometheus/templates/server-service.yaml | 59 + .../templates/server-serviceaccount.yaml | 10 + .../templates/server-statefulset.yaml | 222 +++ .../prometheus/templates/server-vpa.yaml | 24 + .../feast/charts/prometheus/values.yaml | 1514 +++++++++++++++++ infra/charts/feast/charts/redis/.helmignore | 3 + infra/charts/feast/charts/redis/Chart.yaml | 19 + infra/charts/feast/charts/redis/OWNERS | 18 + infra/charts/feast/charts/redis/README.md | 169 ++ .../feast/charts/redis/ci/default-values.yaml | 1 + .../feast/charts/redis/ci/dev-values.yaml | 9 + .../charts/redis/ci/extra-flags-values.yaml | 11 + .../redis/ci/insecure-sentinel-values.yaml | 524 ++++++ .../redis/ci/production-sentinel-values.yaml | 524 ++++++ .../charts/redis/ci/production-values.yaml | 525 ++++++ .../charts/redis/ci/redis-lib-values.yaml | 13 + .../redis/ci/redisgraph-module-values.yaml | 10 + .../feast/charts/redis/templates/NOTES.txt | 104 ++ .../feast/charts/redis/templates/_helpers.tpl | 355 ++++ .../charts/redis/templates/configmap.yaml | 52 + .../charts/redis/templates/headless-svc.yaml | 24 + .../redis/templates/health-configmap.yaml | 134 ++ .../redis/templates/metrics-prometheus.yaml | 30 + .../charts/redis/templates/metrics-svc.yaml | 30 + .../charts/redis/templates/networkpolicy.yaml | 73 + .../redis/templates/prometheusrule.yaml | 23 + .../feast/charts/redis/templates/psp.yaml | 42 + .../templates/redis-master-statefulset.yaml | 419 +++++ .../redis/templates/redis-master-svc.yaml | 39 + .../charts/redis/templates/redis-role.yaml | 21 + .../redis/templates/redis-rolebinding.yaml | 18 + .../redis/templates/redis-serviceaccount.yaml | 11 + .../templates/redis-slave-statefulset.yaml | 437 +++++ .../redis/templates/redis-slave-svc.yaml | 40 + .../templates/redis-with-sentinel-svc.yaml | 40 + .../feast/charts/redis/templates/secret.yaml | 14 + .../feast/charts/redis/values-production.yaml | 630 +++++++ .../feast/charts/redis/values.schema.json | 168 ++ infra/charts/feast/charts/redis/values.yaml | 631 +++++++ .../charts/feast/files/img/dataflow-jobs.png | Bin 0 -> 29728 bytes .../feast/files/img/prometheus-server.png | Bin 0 -> 84787 bytes infra/charts/feast/requirements.lock | 6 - infra/charts/feast/requirements.yaml | 32 +- .../tests/test-feast-batch-serving.yaml | 114 ++ .../tests/test-feast-online-serving.yaml | 102 ++ infra/charts/feast/values-batch-serving.yaml | 22 + .../charts/feast/values-dataflow-runner.yaml | 100 ++ infra/charts/feast/values-demo.yaml | 84 - .../charts/feast/values-existing-secret.yaml | 10 + infra/charts/feast/values-external-store.yaml | 5 - infra/charts/feast/values-production.yaml | 4 - infra/charts/feast/values.yaml | 273 +-- 216 files changed, 17542 insertions(+), 1143 deletions(-) create mode 100644 infra/charts/feast/.helmdocsignore create mode 100644 infra/charts/feast/README.md.gotmpl create mode 100644 infra/charts/feast/charts/feast-core/README.md delete mode 100644 infra/charts/feast/charts/feast-core/charts/kafka-0.20.1.tgz delete mode 100644 infra/charts/feast/charts/feast-core/charts/postgresql-6.5.5.tgz delete mode 100644 infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/README.md delete mode 100644 infra/charts/feast/charts/feast-core/requirements.yaml create mode 100644 infra/charts/feast/charts/feast-serving/README.md delete mode 100644 infra/charts/feast/charts/feast-serving/charts/redis-9.5.0.tgz delete mode 100644 infra/charts/feast/charts/feast-serving/requirements.yaml create mode 100644 infra/charts/feast/charts/grafana/.helmignore create mode 100644 infra/charts/feast/charts/grafana/Chart.yaml create mode 100644 infra/charts/feast/charts/grafana/OWNERS create mode 100644 infra/charts/feast/charts/grafana/README.md create mode 100644 infra/charts/feast/charts/grafana/ci/default-values.yaml create mode 100644 infra/charts/feast/charts/grafana/ci/with-dashboard-json-values.yaml create mode 100644 infra/charts/feast/charts/grafana/ci/with-dashboard-values.yaml create mode 100644 infra/charts/feast/charts/grafana/dashboards/custom-dashboard.json create mode 100644 infra/charts/feast/charts/grafana/templates/NOTES.txt create mode 100644 infra/charts/feast/charts/grafana/templates/_helpers.tpl create mode 100644 infra/charts/feast/charts/grafana/templates/_pod.tpl create mode 100644 infra/charts/feast/charts/grafana/templates/clusterrole.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/clusterrolebinding.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/configmap-dashboard-provider.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/configmap.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/dashboards-json-configmap.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/deployment.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/headless-service.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/ingress.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/poddisruptionbudget.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/podsecuritypolicy.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/pvc.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/role.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/rolebinding.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/secret-env.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/secret.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/service.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/serviceaccount.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/statefulset.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-configmap.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-podsecuritypolicy.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-role.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-rolebinding.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-serviceaccount.yaml create mode 100644 infra/charts/feast/charts/grafana/templates/tests/test.yaml create mode 100644 infra/charts/feast/charts/grafana/values.yaml rename infra/charts/feast/charts/{feast-core => kafka}/.helmignore (97%) create mode 100755 infra/charts/feast/charts/kafka/Chart.yaml create mode 100644 infra/charts/feast/charts/kafka/OWNERS create mode 100644 infra/charts/feast/charts/kafka/README.md create mode 100644 infra/charts/feast/charts/kafka/charts/zookeeper-2.1.0.tgz create mode 100644 infra/charts/feast/charts/kafka/requirements.lock create mode 100644 infra/charts/feast/charts/kafka/requirements.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/NOTES.txt create mode 100644 infra/charts/feast/charts/kafka/templates/_helpers.tpl create mode 100644 infra/charts/feast/charts/kafka/templates/configmap-config.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/configmap-jmx.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/deployment-kafka-exporter.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/job-config.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/podisruptionbudget.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/prometheusrules.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/service-brokers-external.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/service-brokers.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/service-headless.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/servicemonitors.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/statefulset.yaml create mode 100644 infra/charts/feast/charts/kafka/templates/tests/test_topic_create_consume_produce.yaml create mode 100644 infra/charts/feast/charts/kafka/values.yaml create mode 100644 infra/charts/feast/charts/postgresql/.helmignore create mode 100644 infra/charts/feast/charts/postgresql/Chart.yaml create mode 100644 infra/charts/feast/charts/postgresql/OWNERS create mode 100644 infra/charts/feast/charts/postgresql/README.md create mode 100644 infra/charts/feast/charts/postgresql/ci/default-values.yaml create mode 100644 infra/charts/feast/charts/postgresql/ci/shmvolume-disabled-values.yaml create mode 100644 infra/charts/feast/charts/postgresql/files/README.md create mode 100644 infra/charts/feast/charts/postgresql/files/conf.d/README.md create mode 100644 infra/charts/feast/charts/postgresql/files/docker-entrypoint-initdb.d/README.md create mode 100644 infra/charts/feast/charts/postgresql/templates/NOTES.txt create mode 100644 infra/charts/feast/charts/postgresql/templates/_helpers.tpl create mode 100644 infra/charts/feast/charts/postgresql/templates/configmap.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/extended-config-configmap.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/initialization-configmap.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/metrics-configmap.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/metrics-svc.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/networkpolicy.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/prometheusrule.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/secrets.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/serviceaccount.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/servicemonitor.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/statefulset-slaves.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/statefulset.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/svc-headless.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/svc-read.yaml create mode 100644 infra/charts/feast/charts/postgresql/templates/svc.yaml create mode 100644 infra/charts/feast/charts/postgresql/values-production.yaml create mode 100644 infra/charts/feast/charts/postgresql/values.schema.json create mode 100644 infra/charts/feast/charts/postgresql/values.yaml rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/.helmignore (100%) rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/Chart.yaml (100%) create mode 100644 infra/charts/feast/charts/prometheus-statsd-exporter/README.md rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/templates/NOTES.txt (100%) rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/templates/_helpers.tpl (100%) rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/templates/config.yaml (100%) rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/templates/deployment.yaml (97%) rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/templates/pvc.yaml (100%) rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/templates/service.yaml (69%) rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/templates/serviceaccount.yaml (100%) rename infra/charts/feast/charts/{feast-core/charts => }/prometheus-statsd-exporter/values.yaml (96%) rename infra/charts/feast/charts/{feast-serving => prometheus}/.helmignore (97%) create mode 100644 infra/charts/feast/charts/prometheus/Chart.yaml create mode 100644 infra/charts/feast/charts/prometheus/OWNERS create mode 100644 infra/charts/feast/charts/prometheus/README.md create mode 100644 infra/charts/feast/charts/prometheus/requirements.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/NOTES.txt create mode 100644 infra/charts/feast/charts/prometheus/templates/_helpers.tpl create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrole.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrolebinding.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-configmap.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-deployment.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-ingress.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-networkpolicy.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-pdb.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-podsecuritypolicy.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-pvc.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-service-headless.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-service.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-serviceaccount.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-statefulset.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-daemonset.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-podsecuritypolicy.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-role.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-rolebinding.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-service.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-serviceaccount.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrole.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrolebinding.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-deployment.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-ingress.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-networkpolicy.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-pdb.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-podsecuritypolicy.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-pvc.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-service.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-serviceaccount.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-clusterrole.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-clusterrolebinding.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-configmap.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-deployment.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-ingress.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-networkpolicy.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-pdb.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-podsecuritypolicy.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-pvc.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-service-headless.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-service.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-serviceaccount.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-statefulset.yaml create mode 100644 infra/charts/feast/charts/prometheus/templates/server-vpa.yaml create mode 100644 infra/charts/feast/charts/prometheus/values.yaml create mode 100644 infra/charts/feast/charts/redis/.helmignore create mode 100644 infra/charts/feast/charts/redis/Chart.yaml create mode 100644 infra/charts/feast/charts/redis/OWNERS create mode 100644 infra/charts/feast/charts/redis/README.md create mode 100644 infra/charts/feast/charts/redis/ci/default-values.yaml create mode 100644 infra/charts/feast/charts/redis/ci/dev-values.yaml create mode 100644 infra/charts/feast/charts/redis/ci/extra-flags-values.yaml create mode 100644 infra/charts/feast/charts/redis/ci/insecure-sentinel-values.yaml create mode 100644 infra/charts/feast/charts/redis/ci/production-sentinel-values.yaml create mode 100644 infra/charts/feast/charts/redis/ci/production-values.yaml create mode 100644 infra/charts/feast/charts/redis/ci/redis-lib-values.yaml create mode 100644 infra/charts/feast/charts/redis/ci/redisgraph-module-values.yaml create mode 100644 infra/charts/feast/charts/redis/templates/NOTES.txt create mode 100644 infra/charts/feast/charts/redis/templates/_helpers.tpl create mode 100644 infra/charts/feast/charts/redis/templates/configmap.yaml create mode 100644 infra/charts/feast/charts/redis/templates/headless-svc.yaml create mode 100644 infra/charts/feast/charts/redis/templates/health-configmap.yaml create mode 100644 infra/charts/feast/charts/redis/templates/metrics-prometheus.yaml create mode 100644 infra/charts/feast/charts/redis/templates/metrics-svc.yaml create mode 100644 infra/charts/feast/charts/redis/templates/networkpolicy.yaml create mode 100644 infra/charts/feast/charts/redis/templates/prometheusrule.yaml create mode 100644 infra/charts/feast/charts/redis/templates/psp.yaml create mode 100755 infra/charts/feast/charts/redis/templates/redis-master-statefulset.yaml create mode 100644 infra/charts/feast/charts/redis/templates/redis-master-svc.yaml create mode 100644 infra/charts/feast/charts/redis/templates/redis-role.yaml create mode 100644 infra/charts/feast/charts/redis/templates/redis-rolebinding.yaml create mode 100644 infra/charts/feast/charts/redis/templates/redis-serviceaccount.yaml create mode 100755 infra/charts/feast/charts/redis/templates/redis-slave-statefulset.yaml create mode 100644 infra/charts/feast/charts/redis/templates/redis-slave-svc.yaml create mode 100644 infra/charts/feast/charts/redis/templates/redis-with-sentinel-svc.yaml create mode 100644 infra/charts/feast/charts/redis/templates/secret.yaml create mode 100644 infra/charts/feast/charts/redis/values-production.yaml create mode 100644 infra/charts/feast/charts/redis/values.schema.json create mode 100644 infra/charts/feast/charts/redis/values.yaml create mode 100644 infra/charts/feast/files/img/dataflow-jobs.png create mode 100644 infra/charts/feast/files/img/prometheus-server.png delete mode 100644 infra/charts/feast/requirements.lock create mode 100644 infra/charts/feast/templates/tests/test-feast-batch-serving.yaml create mode 100644 infra/charts/feast/templates/tests/test-feast-online-serving.yaml create mode 100644 infra/charts/feast/values-batch-serving.yaml create mode 100644 infra/charts/feast/values-dataflow-runner.yaml delete mode 100644 infra/charts/feast/values-demo.yaml create mode 100644 infra/charts/feast/values-existing-secret.yaml delete mode 100644 infra/charts/feast/values-external-store.yaml delete mode 100644 infra/charts/feast/values-production.yaml diff --git a/infra/charts/feast/.helmdocsignore b/infra/charts/feast/.helmdocsignore new file mode 100644 index 00000000000..21848990474 --- /dev/null +++ b/infra/charts/feast/.helmdocsignore @@ -0,0 +1,6 @@ +charts/postgresql +charts/kafka +charts/redis +charts/prometheus-statsd-exporter +charts/prometheus +charts/grafana diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index c8f328548a9..c58ad2a1529 100644 --- a/infra/charts/feast/Chart.yaml +++ b/infra/charts/feast/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 -description: A Helm chart to install Feast on kubernetes +description: Feature store for machine learning. name: feast -version: 0.4.4 +version: 0.4.6 diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index e93b687f191..36f19730308 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -1,251 +1,378 @@ -# Feast Chart +feast +===== -This directory provides the Helm chart for Feast installation. +Feature store for machine learning. Current chart version is `0.4.6` -This chart installs Feast Core and Feast Serving components of Feast, along with -the required and optional dependencies. Components and dependencies can be -enabled or disabled by changing the corresponding `enabled` flag. Feast Core and -Feast Serving are subcharts of this parent Feast chart. The structure of the charts -are as follows: +## TL;DR; +```bash +# Install Feast with with Online Serving and Beam DirectRunner +helm repo add feast-charts https://feast-charts.storage.googleapis.com +helm repo update +helm install --name myrelease feast-charts/feast ``` -feast // top level feast chart -│ -├── feast-core // feast-core subchart -│ ├── postgresql // Postgresql dependency for feast-core (Feast database) -│ └── kafka // Kafka dependency for feast-core (default stream source) -│ -├── feast-serving-online // feast-serving subchart -│ └── redis // Redis dependency for installation of store together with feast-serving -│ -└── feast-serving-batch // feast-serving subchart -``` + +## Introduction +This chart install Feast deployment on a Kubernetes cluster using the [Helm](https://v2.helm.sh/docs/using_helm/#installing-helm) package manager. ## Prerequisites -- Kubernetes 1.13 or newer cluster -- Helm 2.15.2 or newer +- Kubernetes 1.12+ +- Helm 2.15+ (not tested with Helm 3) +- Persistent Volume support on the underlying infrastructure -## Resources Required -The chart deploys pods that consume minimum resources as specified in the resources configuration parameter. +## Chart requirements -## Installing the Chart +The chart dependencies are bundled in this chart so Feast users do need to run +`helm dep update` to update the dependencies. It also allows Feast chart +maintainers to set reasonable defaults values for the dependencies so end users +of Feast are not overwhelmed with the available configuration. -Add repository for Feast chart: +| Name | Version | +|------|---------| +| [Feast Core](./charts/feast-core/README.md) | 0.4.6 | +| [Feast Serving](./charts/feast-serving/README.md) | 0.4.6 | +| [Postgresql](./charts/postgresql/README.md) | 8.6.1 | +| [Kafka](./charts/kafka/README.md) | 0.20.8 | +| [Redis](./charts/redis/README.md) | 10.5.6 | +| [Prometheus Statsd Exporter](./charts/prometheus-statsd-exporter/README.md) | 0.1.2 | +| [Prometheus](./charts/prometheus/README.md) | 11.0.2 | +| [Grafana](./charts/grafana/README.md) | 5.0.5 | + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| feast-batch-serving.enabled | bool | `false` | Flag to install Feast Batch Serving | +| feast-core.enabled | bool | `true` | Flag to install Feast Core | +| feast-online-serving.enabled | bool | `true` | Flag to install Feast Online Serving | +| grafana.enabled | bool | `true` | Flag to install Grafana | +| kafka.enabled | bool | `true` | Flag to install Kafka | +| postgresql.enabled | bool | `true` | Flag to install Postgresql | +| prometheus-statsd-exporter.enabled | bool | `true` | Flag to install StatsD to Prometheus Exporter | +| prometheus.enabled | bool | `true` | Flag to install Prometheus | +| redis.enabled | bool | `true` | Flag to install Redis | + +## Configuration and installation details + +The default configuration will install Feast with Online Serving. Ingestion +of features uses Beam [DirectRunner](https://beam.apache.org/documentation/runners/direct/) +that runs on the same container where Feast Core is running. To test the installation: ```bash -helm repo add feast-charts https://feast-charts.storage.googleapis.com -helm repo update +helm test myrelease + +# If the installation is successful, the following should be printed +RUNNING: myrelease-feast-online-serving-test +PASSED: myrelease-feast-online-serving-test +RUNNING: myrelease-grafana-test +PASSED: myrelease-grafana-test +RUNNING: myrelease-test-topic-create-consume-produce +PASSED: myrelease-test-topic-create-consume-produce + +# In order to check the logs from the test +kubectl logs myrelease-feast-online-serving-test +``` + +> The test pods can be safely deleted after the test finishes. +> Check the yaml files in `templates/tests/` folder to see the processes +> the test pods execute. + +### Feast metrics + +Feast default installation includes Grafana, StatsD exporter and Prometheus. Request +metrics from Feast Core and Feast Serving, as well as ingestion statistic from +Feast Ingestion are accessible from Prometheus and Grafana dashboard. The following +show a quick example how to access the metrics. + +``` +# Forwards local port 9090 to the Prometheus server pod +kubectl port-forward svc/myrelease-prometheus-server 9090:80 ``` -Install Feast release with minimal features, without batch serving and persistence: +Visit http://localhost:9090 to access the Prometheus server: + +![Prometheus Server](files/img/prometheus-server.png?raw=true) + +### Enable Batch Serving + +To install Feast Batch Serving for retrieval of historical features in offline +training, access to BigQuery is required. First, create a [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) key that +will provide the credentials to access BigQuery. Grant the service account `editor` +role so it has write permissions to BigQuery and Cloud Storage. + +> In production, it is advised to give only the required [permissions](foo-feast-batch-serving-test) for the +> the service account, versus `editor` role which is very permissive. + +Create a Kubernetes secret for the service account JSON file: ```bash -RELEASE_NAME=demo -helm install feast-charts/feast --name $RELEASE_NAME -f values-demo.yaml +# By default Feast expects the secret to be named "feast-gcp-service-account" +# and the JSON file to be named "credentials.json" +kubectl create secret generic feast-gcp-service-account --from-file=credentials.json ``` -Install Feast release for typical use cases, with batch and online serving: +Create a new Cloud Storage bucket (if not exists) and make sure the service +account has write access to the bucket: ```bash -# To install Feast Batch serving, BigQuery and Google Cloud service account -# is required. The service account needs to have these roles: -# - bigquery.dataEditor -# - bigquery.jobUser -# -# Assuming a service account JSON file has been downloaded to /home/user/key.json, -# run the following command to create a secret in Kubernetes -# (make sure the file name is called key.json): -kubectl create secret generic feast-gcp-service-account --from-file=/home/user/key.json - -# Set these required configuration in Feast Batch Serving -STAGING_LOCATION=gs://bucket/path -PROJECT_ID=google-cloud-project-id -DATASET_ID=bigquery-dataset-id - -# Install the Helm release using default values.yaml -helm install feast-charts/feast --name feast \ - --set feast-serving-batch."application\.yaml".feast.jobs.staging-location=$STAGING_LOCATION \ - --set feast-serving-batch."store\.yaml".bigquery_config.project_id=$PROJECT_ID \ - --set feast-serving-batch."store\.yaml".bigquery_config.dataset_id=$DATASET_ID +gsutil mb +``` + +Use the following Helm values to enable Batch Serving: +```yaml +# values-batch-serving.yaml +feast-core: + gcpServiceAccount: + enabled: true + +feast-batch-serving: + enabled: true + store.yaml: + name: bigquery-store + type: BIGQUERY + bigquery_config: + project_id: + dataset_id: + subscriptions: + - project: "*" + name: "*" + version: "*" + application-override.yaml: + feast: + jobs: + staging-location: gs:///staging-location + gcpServiceAccount: + enabled: true ``` -## Parameters - -The following table lists the configurable parameters of the Feast chart and their default values. - -| Parameter | Description | Default -| --------- | ----------- | ------- -| `feast-core.enabled` | Flag to install Feast Core | `true` -| `feast-core.postgresql.enabled` | Flag to install Postgresql as Feast database | `true` -| `feast-core.postgresql.postgresqlDatabase` | Name of the database used by Feast Core | `feast` -| `feast-core.postgresql.postgresqlUsername` | Username to authenticate to Feast database | `postgres` -| `feast-core.postgresql.postgresqlPassword` | Passsword to authenticate to Feast database | `password` -| `feast-core.kafka.enabled` | Flag to install Kafka as the default source for Feast | `true` -| `feast-core.kafka.topics[0].name` | Default topic name in Kafka| `feast` -| `feast-core.kafka.topics[0].replicationFactor` | No of replication factor for the topic| `1` -| `feast-core.kafka.topics[0].partitions` | No of partitions for the topic | `1` -| `feast-core.prometheus-statsd-exporter.enabled` | Flag to install Prometheus StatsD Exporter | `false` -| `feast-core.prometheus-statsd-exporter.*` | Refer to this [link](charts/feast-core/charts/prometheus-statsd-exporter/values.yaml | -| `feast-core.replicaCount` | No of pods to create | `1` -| `feast-core.image.repository` | Repository for Feast Core Docker image | `gcr.io/kf-feast/feast-core` -| `feast-core.image.tag` | Tag for Feast Core Docker image | `0.4.4` -| `feast-core.image.pullPolicy` | Image pull policy for Feast Core Docker image | `IfNotPresent` -| `feast-core.prometheus.enabled` | Add annotations to enable Prometheus scraping | `false` -| `feast-core.application.yaml` | Configuration for Feast Core application | Refer to this [link](charts/feast-core/values.yaml) -| `feast-core.springConfigMountPath` | Directory to mount application.yaml | `/etc/feast/feast-core` -| `feast-core.gcpServiceAccount.useExistingSecret` | Flag to use existing secret for GCP service account | `false` -| `feast-core.gcpServiceAccount.existingSecret.name` | Secret name for the service account | `feast-gcp-service-account` -| `feast-core.gcpServiceAccount.existingSecret.key` | Secret key for the service account | `key.json` -| `feast-core.gcpServiceAccount.mountPath` | Directory to mount the JSON key file | `/etc/gcloud/service-accounts` -| `feast-core.gcpProjectId` | Project ID to set `GOOGLE_CLOUD_PROJECT` to change default project used by SDKs | `""` -| `feast-core.jarPath` | Path to Jar file in the Docker image | `/opt/feast/feast-core.jar` -| `feast-core.jvmOptions` | Options for the JVM | `[]` -| `feast-core.logLevel` | Application logging level | `warn` -| `feast-core.logType` | Application logging type (`JSON` or `Console`) | `JSON` -| `feast-core.springConfigProfiles` | Map of profile name to file content for additional Spring profiles | `{}` -| `feast-core.springConfigProfilesActive` | CSV of profiles to enable from `springConfigProfiles` | `""` -| `feast-core.livenessProbe.enabled` | Flag to enable liveness probe | `true` -| `feast-core.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | `60` -| `feast-core.livenessProbe.periodSeconds` | How often to perform the probe | `10` -| `feast-core.livenessProbe.timeoutSeconds` | Timeout duration for the probe | `5` -| `feast-core.livenessProbe.successThreshold` | Minimum no of consecutive successes for the probe to be considered successful | `1` -| `feast-core.livenessProbe.failureThreshold` | Minimum no of consecutive failures for the probe to be considered failed | `5` -| `feast-core.readinessProbe.enabled` | Flag to enable readiness probe | `true` -| `feast-core.readinessProbe.initialDelaySeconds` | Delay before readiness probe is initiated | `30` -| `feast-core.readinessProbe.periodSeconds` | How often to perform the probe | `10` -| `feast-core.readinessProbe.timeoutSeconds` | Timeout duration for the probe | `10` -| `feast-core.readinessProbe.successThreshold` | Minimum no of consecutive successes for the probe to be considered successful | `1` -| `feast-core.service.type` | Kubernetes Service Type | `ClusterIP` -| `feast-core.http.port` | Kubernetes Service port for HTTP request| `80` -| `feast-core.http.targetPort` | Container port for HTTP request | `8080` -| `feast-core.grpc.port` | Kubernetes Service port for GRPC request| `6565` -| `feast-core.grpc.targetPort` | Container port for GRPC request| `6565` -| `feast-core.resources` | CPU and memory allocation for the pod | `{}` -| `feast-core.ingress` | See *Ingress Parameters* [below](#ingress-parameters) | `{}` -| `feast-serving-online.enabled` | Flag to install Feast Online Serving | `true` -| `feast-serving-online.redis.enabled` | Flag to install Redis in Feast Serving | `false` -| `feast-serving-online.redis.usePassword` | Flag to use password to access Redis | `false` -| `feast-serving-online.redis.cluster.enabled` | Flag to enable Redis cluster | `false` -| `feast-serving-online.core.enabled` | Flag for Feast Serving to use Feast Core in the same Helm release | `true` -| `feast-serving-online.replicaCount` | No of pods to create | `1` -| `feast-serving-online.image.repository` | Repository for Feast Serving Docker image | `gcr.io/kf-feast/feast-serving` -| `feast-serving-online.image.tag` | Tag for Feast Serving Docker image | `0.4.4` -| `feast-serving-online.image.pullPolicy` | Image pull policy for Feast Serving Docker image | `IfNotPresent` -| `feast-serving-online.prometheus.enabled` | Add annotations to enable Prometheus scraping | `true` -| `feast-serving-online.application.yaml` | Application configuration for Feast Serving | Refer to this [link](charts/feast-serving/values.yaml) -| `feast-serving-online.store.yaml` | Store configuration for Feast Serving | Refer to this [link](charts/feast-serving/values.yaml) -| `feast-serving-online.springConfigMountPath` | Directory to mount application.yaml and store.yaml | `/etc/feast/feast-serving` -| `feast-serving-online.gcpServiceAccount.useExistingSecret` | Flag to use existing secret for GCP service account | `false` -| `feast-serving-online.gcpServiceAccount.existingSecret.name` | Secret name for the service account | `feast-gcp-service-account` -| `feast-serving-online.gcpServiceAccount.existingSecret.key` | Secret key for the service account | `key.json` -| `feast-serving-online.gcpServiceAccount.mountPath` | Directory to mount the JSON key file | `/etc/gcloud/service-accounts` -| `feast-serving-online.gcpProjectId` | Project ID to set `GOOGLE_CLOUD_PROJECT` to change default project used by SDKs | `""` -| `feast-serving-online.jarPath` | Path to Jar file in the Docker image | `/opt/feast/feast-serving.jar` -| `feast-serving-online.jvmOptions` | Options for the JVM | `[]` -| `feast-serving-online.logLevel` | Application logging level | `warn` -| `feast-serving-online.logType` | Application logging type (`JSON` or `Console`) | `JSON` -| `feast-serving-online.springConfigProfiles` | Map of profile name to file content for additional Spring profiles | `{}` -| `feast-serving-online.springConfigProfilesActive` | CSV of profiles to enable from `springConfigProfiles` | `""` -| `feast-serving-online.livenessProbe.enabled` | Flag to enable liveness probe | `true` -| `feast-serving-online.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | `60` -| `feast-serving-online.livenessProbe.periodSeconds` | How often to perform the probe | `10` -| `feast-serving-online.livenessProbe.timeoutSeconds` | Timeout duration for the probe | `5` -| `feast-serving-online.livenessProbe.successThreshold` | Minimum no of consecutive successes for the probe to be considered successful | `1` -| `feast-serving-online.livenessProbe.failureThreshold` | Minimum no of consecutive failures for the probe to be considered failed | `5` -| `feast-serving-online.readinessProbe.enabled` | Flag to enable readiness probe | `true` -| `feast-serving-online.readinessProbe.initialDelaySeconds` | Delay before readiness probe is initiated | `30` -| `feast-serving-online.readinessProbe.periodSeconds` | How often to perform the probe | `10` -| `feast-serving-online.readinessProbe.timeoutSeconds` | Timeout duration for the probe | `10` -| `feast-serving-online.readinessProbe.successThreshold` | Minimum no of consecutive successes for the probe to be considered successful | `1` -| `feast-serving-online.service.type` | Kubernetes Service Type | `ClusterIP` -| `feast-serving-online.http.port` | Kubernetes Service port for HTTP request| `80` -| `feast-serving-online.http.targetPort` | Container port for HTTP request | `8080` -| `feast-serving-online.grpc.port` | Kubernetes Service port for GRPC request| `6566` -| `feast-serving-online.grpc.targetPort` | Container port for GRPC request| `6566` -| `feast-serving-online.resources` | CPU and memory allocation for the pod | `{}` -| `feast-serving-online.ingress` | See *Ingress Parameters* [below](#ingress-parameters) | `{}` -| `feast-serving-batch.enabled` | Flag to install Feast Batch Serving | `true` -| `feast-serving-batch.redis.enabled` | Flag to install Redis in Feast Serving | `false` -| `feast-serving-batch.redis.usePassword` | Flag to use password to access Redis | `false` -| `feast-serving-batch.redis.cluster.enabled` | Flag to enable Redis cluster | `false` -| `feast-serving-batch.core.enabled` | Flag for Feast Serving to use Feast Core in the same Helm release | `true` -| `feast-serving-batch.replicaCount` | No of pods to create | `1` -| `feast-serving-batch.image.repository` | Repository for Feast Serving Docker image | `gcr.io/kf-feast/feast-serving` -| `feast-serving-batch.image.tag` | Tag for Feast Serving Docker image | `0.4.4` -| `feast-serving-batch.image.pullPolicy` | Image pull policy for Feast Serving Docker image | `IfNotPresent` -| `feast-serving-batch.prometheus.enabled` | Add annotations to enable Prometheus scraping | `true` -| `feast-serving-batch.application.yaml` | Application configuration for Feast Serving | Refer to this [link](charts/feast-serving/values.yaml) -| `feast-serving-batch.store.yaml` | Store configuration for Feast Serving | Refer to this [link](charts/feast-serving/values.yaml) -| `feast-serving-batch.springConfigMountPath` | Directory to mount application.yaml and store.yaml | `/etc/feast/feast-serving` -| `feast-serving-batch.gcpServiceAccount.useExistingSecret` | Flag to use existing secret for GCP service account | `false` -| `feast-serving-batch.gcpServiceAccount.existingSecret.name` | Secret name for the service account | `feast-gcp-service-account` -| `feast-serving-batch.gcpServiceAccount.existingSecret.key` | Secret key for the service account | `key.json` -| `feast-serving-batch.gcpServiceAccount.mountPath` | Directory to mount the JSON key file | `/etc/gcloud/service-accounts` -| `feast-serving-batch.gcpProjectId` | Project ID to set `GOOGLE_CLOUD_PROJECT` to change default project used by SDKs | `""` -| `feast-serving-batch.jarPath` | Path to Jar file in the Docker image | `/opt/feast/feast-serving.jar` -| `feast-serving-batch.jvmOptions` | Options for the JVM | `[]` -| `feast-serving-batch.logLevel` | Application logging level | `warn` -| `feast-serving-batch.logType` | Application logging type (`JSON` or `Console`) | `JSON` -| `feast-serving-batch.springConfigProfiles` | Map of profile name to file content for additional Spring profiles | `{}` -| `feast-serving-batch.springConfigProfilesActive` | CSV of profiles to enable from `springConfigProfiles` | `""` -| `feast-serving-batch.livenessProbe.enabled` | Flag to enable liveness probe | `true` -| `feast-serving-batch.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | `60` -| `feast-serving-batch.livenessProbe.periodSeconds` | How often to perform the probe | `10` -| `feast-serving-batch.livenessProbe.timeoutSeconds` | Timeout duration for the probe | `5` -| `feast-serving-batch.livenessProbe.successThreshold` | Minimum no of consecutive successes for the probe to be considered successful | `1` -| `feast-serving-batch.livenessProbe.failureThreshold` | Minimum no of consecutive failures for the probe to be considered failed | `5` -| `feast-serving-batch.readinessProbe.enabled` | Flag to enable readiness probe | `true` -| `feast-serving-batch.readinessProbe.initialDelaySeconds` | Delay before readiness probe is initiated | `30` -| `feast-serving-batch.readinessProbe.periodSeconds` | How often to perform the probe | `10` -| `feast-serving-batch.readinessProbe.timeoutSeconds` | Timeout duration for the probe | `10` -| `feast-serving-batch.readinessProbe.successThreshold` | Minimum no of consecutive successes for the probe to be considered successful | `1` -| `feast-serving-batch.service.type` | Kubernetes Service Type | `ClusterIP` -| `feast-serving-batch.http.port` | Kubernetes Service port for HTTP request| `80` -| `feast-serving-batch.http.targetPort` | Container port for HTTP request | `8080` -| `feast-serving-batch.grpc.port` | Kubernetes Service port for GRPC request| `6566` -| `feast-serving-batch.grpc.targetPort` | Container port for GRPC request| `6566` -| `feast-serving-batch.resources` | CPU and memory allocation for the pod | `{}` -| `feast-serving-batch.ingress` | See *Ingress Parameters* [below](#ingress-parameters) | `{}` - -## Ingress Parameters - -The following table lists the configurable parameters of the ingress section for each Feast module. - -Note, there are two ingresses available for each module - `grpc` and `http`. - -| Parameter | Description | Default -| ----------------------------- | ----------- | ------- -| `ingress.grcp.enabled` | Enables an ingress (endpoint) for the gRPC server | `false` -| `ingress.grcp.*` | See below | -| `ingress.http.enabled` | Enables an ingress (endpoint) for the HTTP server | `false` -| `ingress.http.*` | See below | -| `ingress.*.class` | Value for `kubernetes.io/ingress.class` | `nginx` -| `ingress.*.hosts` | List of host-names for the ingress | `[]` -| `ingress.*.annotations` | Additional ingress annotations | `{}` -| `ingress.*.https.enabled` | Add a tls section to the ingress | `true` -| `ingress.*.https.secretNames` | Map of hostname to TLS secret name | `{}` If not specified, defaults to `domain-tld-tls` e.g. `feast.example.com` uses secret `example-com-tls` -| `ingress.*.auth.enabled` | Enable auth on the ingress (only applicable for `nginx` type | `false` -| `ingress.*.auth.signinHost` | External hostname of the OAuth2 proxy to use | First item in `ingress.hosts`, replacing the sub-domain with 'auth' e.g. `feast.example.com` uses `auth.example.com` -| `ingress.*.auth.authUrl` | Internal URI to internal auth endpoint | `http://auth-server.auth-ns.svc.cluster.local/auth` -| `ingress.*.whitelist` | Subnet masks to whitelist (i.e. value for `nginx.ingress.kubernetes.io/whitelist-source-range`) | `"""` - -To enable all the ingresses will a config like the following (while also adding the hosts etc): +> To delete the previous release, run `helm delete --purge myrelease` +> Note this will not delete the persistent volume that has been claimed (PVC). +> In a test cluster, run `kubectl delete pvc --all` to delete all claimed PVCs. + +```bash +# Install a new release +helm install --name myrelease -f values-batch-serving.yaml feast-charts/feast + +# Wait until all pods are created and running/completed (can take about 5m) +kubectl get pods + +# Batch Serving is installed so `helm test` will also test for batch retrieval +helm test myrelease +``` + +### Use DataflowRunner for ingestion + +Apache Beam [DirectRunner](https://beam.apache.org/documentation/runners/direct/) +is not suitable for production use case because it is not easy to scale the +number of workers and there is no convenient API to monitor and manage the +workers. Feast supports [DataflowRunner](https://beam.apache.org/documentation/runners/dataflow/) which is a managed service on Google Cloud. + +> Make sure `feast-gcp-service-account` Kubernetes secret containing the +> service account has been created and the service account has permissions +> to manage Dataflow jobs. + +Since Dataflow workers run outside the Kube cluster and they will need to interact +with Kafka brokers, Redis stores and StatsD server installed in the cluster, +these services need to be exposed for access outside the cluster by setting +`service.type: LoadBalancer`. + +In a typical use case, 5 `LoadBalancer` (internal) IP addresses are required by +Feast when running with `DataflowRunner`. In Google Cloud, these (internal) IP +addresses should be reserved first: +```bash +# Check with your network configuration which IP addresses are available for use +gcloud compute addresses create \ + feast-kafka-1 feast-kafka-2 feast-kafka-3 feast-redis feast-statsd \ + --region --subnet \ + --addresses 10.128.0.11,10.128.0.12,10.128.0.13,10.128.0.14,10.128.0.15 +``` + +Use the following Helm values to enable DataflowRuner (and Batch Serving), +replacing the `<*load_balancer_ip*>` tags with the ones reserved above: ```yaml +# values-dataflow-runner.yaml feast-core: - ingress: - grpc: - enabled: true - http: - enabled: true -feast-serving-online: - ingress: - grpc: - enabled: true - http: - enabled: true -feast-serving-batch: - ingress: - grpc: - enabled: true - http: - enabled: true + gcpServiceAccount: + enabled: true + application-override.yaml: + feast: + stream: + options: + bootstrapServers: + jobs: + runner: DataflowRunner + options: + project: + region: + zone: + tempLocation: + network: + subnetwork: + maxNumWorkers: 1 + autoscalingAlgorithm: THROUGHPUT_BASED + usePublicIps: false + workerMachineType: n1-standard-1 + deadLetterTableSpec: + metrics: + host: + +feast-online-serving: + store.yaml: + name: redis-store + type: REDIS + redis_config: + host: + port: 6379 + subscriptions: + - project: "*" + name: "*" + version: "*" + +feast-batch-serving: + enabled: true + store.yaml: + name: bigquery-store + type: BIGQUERY + bigquery_config: + project_id: + dataset_id: + subscriptions: + - project: "*" + name: "*" + version: "*" + application-override.yaml: + feast: + jobs: + staging-location: + gcpServiceAccount: + enabled: true + +kafka: + external: + enabled: true + type: LoadBalancer + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + firstListenerPort: 31090 + loadBalancerIP: + - + - + - + configurationOverrides: + "advertised.listeners": |- + EXTERNAL://${LOAD_BALANCER_IP}:31090 + "listener.security.protocol.map": |- + PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT + "log.retention.hours": 1 + +redis: + master: + service: + type: LoadBalancer + loadBalancerIP: + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + +prometheus-statsd-exporter: + service: + type: LoadBalancer + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + loadBalancerIP: +``` + +```bash +# Install a new release +helm install --name myrelease -f values-dataflow-runner.yaml feast-charts/feast + +# Wait until all pods are created and running/completed (can take about 5m) +kubectl get pods + +# Test the installation +helm test myrelease ``` +If the tests are successful, Dataflow jobs should appear in Google Cloud console +running features ingestion: https://console.cloud.google.com/dataflow + +![Dataflow Jobs](files/img/dataflow-jobs.png) + +### Production configuration + +#### Secrets management + +The installation examples above automatically create secrets for Postgresql and +Grafana with randomly generated values. However, these secrets are not stable +i.e. running `helm upgrade` will update the secret unintentionally. For +production, the secrets are usually generated first before deployment. In summary, +these are the 3 secrets that Feast requires: + +```bash +kubectl create secret generic feast-postgresql \ + --from-literal=postgresql-password= + +kubectl create secret generic feast-gcp-service-account \ + --from-file=credentials.json + +kubectl create secret generic feast-grafana \ + --from-literal=admin-user=admin \ + --from-literal=admin-password= \ +``` + +With these secrets in place, they can be used like so: +```yaml +# values-existing-secret.yaml +feast-core: + postgresql: + existingSecret: feast-postgresql + +postgresql: + existingSecret: feast-postgresql + +grafana: + admin: + existingSecret: feast-grafana +``` + +#### Resources requests + +The `resources` field in the deployment spec is left empty in the examples. In +production these should be set according to the load each services are expected +to handle and the service level objectives (SLO). Also Feast Core and Serving +is Java application and it is [good practice](https://stackoverflow.com/a/6916718/3949303) +to set the minimum and maximum heap. This is an example reasonable value to set for Feast Serving: + +```yaml +feast-online-serving: + javaOpts: "-Xms2048m -Xmx2048m" + resources: + requests: + memory: "4096Mi" + limits: + memory: "2048Mi" + cpu: "2" +``` + +#### High availability + +Default Feast installation only configures a single instance of Redis +server. If due to network failures or out of memory error Redis is down, +Feast serving will fail to respond to requests. Soon, Feast will support +highly available Redis via [Redis cluster](https://redis.io/topics/cluster-tutorial), +sentinel or additional proxies. + +### Documentation development + +This `README.md` is generated using [helm-docs](https://github.com/norwoodj/helm-docs/). +Run `helm-docs` after changing directory to this folder to regenerate a new `README.md` +when Feast charts or values are modified. \ No newline at end of file diff --git a/infra/charts/feast/README.md.gotmpl b/infra/charts/feast/README.md.gotmpl new file mode 100644 index 00000000000..2c6c4e03b50 --- /dev/null +++ b/infra/charts/feast/README.md.gotmpl @@ -0,0 +1,365 @@ +{{ template "chart.header" . }} + +{{ template "chart.description" . }} {{ template "chart.versionLine" . }} + +## TL;DR; + +```bash +# Install Feast with with Online Serving and Beam DirectRunner +helm repo add feast-charts https://feast-charts.storage.googleapis.com +helm repo update +helm install --name myrelease feast-charts/feast +``` + +## Introduction +This chart install Feast deployment on a Kubernetes cluster using the [Helm](https://v2.helm.sh/docs/using_helm/#installing-helm) package manager. + +## Prerequisites +- Kubernetes 1.12+ +- Helm 2.15+ (not tested with Helm 3) +- Persistent Volume support on the underlying infrastructure + +## Chart requirements + +The chart dependencies are bundled in this chart so Feast users do need to run +`helm dep update` to update the dependencies. It also allows Feast chart +maintainers to set reasonable defaults values for the dependencies so end users +of Feast are not overwhelmed with the available configuration. + +| Name | Version | +|------|---------| +| [Feast Core](./charts/feast-core/README.md) | 0.4.6 | +| [Feast Serving](./charts/feast-serving/README.md) | 0.4.6 | +| [Postgresql](./charts/postgresql/README.md) | 8.6.1 | +| [Kafka](./charts/kafka/README.md) | 0.20.8 | +| [Redis](./charts/redis/README.md) | 10.5.6 | +| [Prometheus Statsd Exporter](./charts/prometheus-statsd-exporter/README.md) | 0.1.2 | +| [Prometheus](./charts/prometheus/README.md) | 11.0.2 | +| [Grafana](./charts/grafana/README.md) | 5.0.5 | + +{{ template "chart.valuesSection" . }} + +## Configuration and installation details + +The default configuration will install Feast with Online Serving. Ingestion +of features uses Beam [DirectRunner](https://beam.apache.org/documentation/runners/direct/) +that runs on the same container where Feast Core is running. To test the installation: +```bash +helm test myrelease + +# If the installation is successful, the following should be printed +RUNNING: myrelease-feast-online-serving-test +PASSED: myrelease-feast-online-serving-test +RUNNING: myrelease-grafana-test +PASSED: myrelease-grafana-test +RUNNING: myrelease-test-topic-create-consume-produce +PASSED: myrelease-test-topic-create-consume-produce + +# In order to check the logs from the test +kubectl logs myrelease-feast-online-serving-test +``` + +> The test pods can be safely deleted after the test finishes. +> Check the yaml files in `templates/tests/` folder to see the processes +> the test pods execute. + +### Feast metrics + +Feast default installation includes Grafana, StatsD exporter and Prometheus. Request +metrics from Feast Core and Feast Serving, as well as ingestion statistic from +Feast Ingestion are accessible from Prometheus and Grafana dashboard. The following +show a quick example how to access the metrics. + +``` +# Forwards local port 9090 to the Prometheus server pod +kubectl port-forward svc/myrelease-prometheus-server 9090:80 +``` + +Visit http://localhost:9090 to access the Prometheus server: + +![Prometheus Server](files/img/prometheus-server.png?raw=true) + +### Enable Batch Serving + +To install Feast Batch Serving for retrieval of historical features in offline +training, access to BigQuery is required. First, create a [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) key that +will provide the credentials to access BigQuery. Grant the service account `editor` +role so it has write permissions to BigQuery and Cloud Storage. + +> In production, it is advised to give only the required [permissions](foo-feast-batch-serving-test) for the +> the service account, versus `editor` role which is very permissive. + +Create a Kubernetes secret for the service account JSON file: +```bash +# By default Feast expects the secret to be named "feast-gcp-service-account" +# and the JSON file to be named "credentials.json" +kubectl create secret generic feast-gcp-service-account --from-file=credentials.json +``` + +Create a new Cloud Storage bucket (if not exists) and make sure the service +account has write access to the bucket: +```bash +gsutil mb +``` + +Use the following Helm values to enable Batch Serving: +```yaml +# values-batch-serving.yaml +feast-core: + gcpServiceAccount: + enabled: true + +feast-batch-serving: + enabled: true + store.yaml: + name: bigquery-store + type: BIGQUERY + bigquery_config: + project_id: + dataset_id: + subscriptions: + - project: "*" + name: "*" + version: "*" + application-override.yaml: + feast: + jobs: + staging-location: gs:///staging-location + gcpServiceAccount: + enabled: true +``` + +> To delete the previous release, run `helm delete --purge myrelease` +> Note this will not delete the persistent volume that has been claimed (PVC). +> In a test cluster, run `kubectl delete pvc --all` to delete all claimed PVCs. + +```bash +# Install a new release +helm install --name myrelease -f values-batch-serving.yaml feast-charts/feast + +# Wait until all pods are created and running/completed (can take about 5m) +kubectl get pods + +# Batch Serving is installed so `helm test` will also test for batch retrieval +helm test myrelease +``` + +### Use DataflowRunner for ingestion + +Apache Beam [DirectRunner](https://beam.apache.org/documentation/runners/direct/) +is not suitable for production use case because it is not easy to scale the +number of workers and there is no convenient API to monitor and manage the +workers. Feast supports [DataflowRunner](https://beam.apache.org/documentation/runners/dataflow/) which is a managed service on Google Cloud. + +> Make sure `feast-gcp-service-account` Kubernetes secret containing the +> service account has been created and the service account has permissions +> to manage Dataflow jobs. + +Since Dataflow workers run outside the Kube cluster and they will need to interact +with Kafka brokers, Redis stores and StatsD server installed in the cluster, +these services need to be exposed for access outside the cluster by setting +`service.type: LoadBalancer`. + +In a typical use case, 5 `LoadBalancer` (internal) IP addresses are required by +Feast when running with `DataflowRunner`. In Google Cloud, these (internal) IP +addresses should be reserved first: +```bash +# Check with your network configuration which IP addresses are available for use +gcloud compute addresses create \ + feast-kafka-1 feast-kafka-2 feast-kafka-3 feast-redis feast-statsd \ + --region --subnet \ + --addresses 10.128.0.11,10.128.0.12,10.128.0.13,10.128.0.14,10.128.0.15 +``` + +Use the following Helm values to enable DataflowRuner (and Batch Serving), +replacing the `<*load_balancer_ip*>` tags with the ones reserved above: + +```yaml +# values-dataflow-runner.yaml +feast-core: + gcpServiceAccount: + enabled: true + application-override.yaml: + feast: + stream: + options: + bootstrapServers: + jobs: + runner: DataflowRunner + options: + project: + region: + zone: + tempLocation: + network: + subnetwork: + maxNumWorkers: 1 + autoscalingAlgorithm: THROUGHPUT_BASED + usePublicIps: false + workerMachineType: n1-standard-1 + deadLetterTableSpec: + metrics: + host: + +feast-online-serving: + store.yaml: + name: redis-store + type: REDIS + redis_config: + host: + port: 6379 + subscriptions: + - project: "*" + name: "*" + version: "*" + +feast-batch-serving: + enabled: true + store.yaml: + name: bigquery-store + type: BIGQUERY + bigquery_config: + project_id: + dataset_id: + subscriptions: + - project: "*" + name: "*" + version: "*" + application-override.yaml: + feast: + jobs: + staging-location: + gcpServiceAccount: + enabled: true + +kafka: + external: + enabled: true + type: LoadBalancer + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + firstListenerPort: 31090 + loadBalancerIP: + - + - + - + configurationOverrides: + "advertised.listeners": |- + EXTERNAL://${LOAD_BALANCER_IP}:31090 + "listener.security.protocol.map": |- + PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT + "log.retention.hours": 1 + +redis: + master: + service: + type: LoadBalancer + loadBalancerIP: + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + +prometheus-statsd-exporter: + service: + type: LoadBalancer + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + loadBalancerIP: +``` + +```bash +# Install a new release +helm install --name myrelease -f values-dataflow-runner.yaml feast-charts/feast + +# Wait until all pods are created and running/completed (can take about 5m) +kubectl get pods + +# Test the installation +helm test myrelease +``` + +If the tests are successful, Dataflow jobs should appear in Google Cloud console +running features ingestion: https://console.cloud.google.com/dataflow + +![Dataflow Jobs](files/img/dataflow-jobs.png) + +### Production configuration + +#### Secrets management + +The installation examples above automatically create secrets for Postgresql and +Grafana with randomly generated values. However, these secrets are not stable +i.e. running `helm upgrade` will update the secret unintentionally. For +production, the secrets are usually generated first before deployment. In summary, +these are the 3 secrets that Feast requires: + +```bash +kubectl create secret generic feast-postgresql \ + --from-literal=postgresql-password= + +kubectl create secret generic feast-gcp-service-account \ + --from-file=credentials.json + +kubectl create secret generic feast-grafana \ + --from-literal=admin-user=admin \ + --from-literal=admin-password= \ +``` + +With these secrets in place, they can be used like so: +```yaml +# values-existing-secret.yaml +feast-core: + postgresql: + existingSecret: feast-postgresql + +postgresql: + existingSecret: feast-postgresql + +grafana: + admin: + existingSecret: feast-grafana +``` + +#### Resources requests + +The `resources` field in the deployment spec is left empty in the examples. In +production these should be set according to the load each services are expected +to handle and the service level objectives (SLO). Also Feast Core and Serving +is Java application and it is [good practice](https://stackoverflow.com/a/6916718/3949303) +to set the minimum and maximum heap. This is an example reasonable value to set for Feast Serving: + +```yaml +feast-online-serving: + javaOpts: "-Xms2048m -Xmx2048m" + resources: + requests: + memory: "4096Mi" + limits: + memory: "2048Mi" + cpu: "2" +``` + +#### High availability + +Default Feast installation only configures a single instance of Redis +server. If due to network failures or out of memory error Redis is down, +Feast serving will fail to respond to requests. Soon, Feast will support +highly available Redis via [Redis cluster](https://redis.io/topics/cluster-tutorial), +sentinel or additional proxies. + +### Documentation development + +This `README.md` is generated using [helm-docs](https://github.com/norwoodj/helm-docs/). +Run `helm-docs` after changing directory to this folder to regenerate a new `README.md` +when Feast charts or values are modified. \ No newline at end of file diff --git a/infra/charts/feast/charts/feast-core/Chart.yaml b/infra/charts/feast/charts/feast-core/Chart.yaml index 86d0699b9ac..e1ee6ea0fd8 100644 --- a/infra/charts/feast/charts/feast-core/Chart.yaml +++ b/infra/charts/feast/charts/feast-core/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 -description: A Helm chart for core component of Feast +description: Feast Core registers feature specifications and manage ingestion jobs. name: feast-core -version: 0.4.4 +version: 0.4.6 diff --git a/infra/charts/feast/charts/feast-core/README.md b/infra/charts/feast/charts/feast-core/README.md new file mode 100644 index 00000000000..f82b4654b17 --- /dev/null +++ b/infra/charts/feast/charts/feast-core/README.md @@ -0,0 +1,65 @@ +feast-core +========== +Feast Core registers feature specifications and manage ingestion jobs. + +Current chart version is `0.4.6` + + + + + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| "application-override.yaml" | object | `{}` | [Configuration override](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml) for Feast Core | +| gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | +| gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | +| gcpServiceAccount.existingSecret.name | string | `"feast-gcp-service-account"` | Name of the existing secret containing the service account | +| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | +| image.repository | string | `"gcr.io/kf-feast/feast-core"` | Docker image repository | +| image.tag | string | `"0.4.6"` | Image tag | +| ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | +| ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | +| ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | +| ingress.grpc.enabled | bool | `false` | Flag to create an ingress resource for the service | +| ingress.grpc.hosts | list | `[]` | List of hostnames to match when routing requests | +| ingress.grpc.https.enabled | bool | `true` | Flag to enable HTTPS | +| ingress.grpc.https.secretNames | object | `{}` | Map of hostname to TLS secret name | +| ingress.grpc.whitelist | string | `""` | Allowed client IP source ranges | +| ingress.http.annotations | object | `{}` | Extra annotations for the ingress | +| ingress.http.auth.authUrl | string | `"http://auth-server.auth-ns.svc.cluster.local/auth"` | URL to an existing authentication service | +| ingress.http.auth.enabled | bool | `false` | Flag to enable auth | +| ingress.http.class | string | `"nginx"` | Which ingress controller to use | +| ingress.http.enabled | bool | `false` | Flag to create an ingress resource for the service | +| ingress.http.hosts | list | `[]` | List of hostnames to match when routing requests | +| ingress.http.https.enabled | bool | `true` | Flag to enable HTTPS | +| ingress.http.https.secretNames | object | `{}` | Map of hostname to TLS secret name | +| ingress.http.whitelist | string | `""` | Allowed client IP source ranges | +| javaOpts | string | `nil` | [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). It is advised for better performance to set the min and max heap:
`-Xms2048m -Xmx2048m` | +| livenessProbe.enabled | bool | `true` | Flag to enabled the probe | +| livenessProbe.failureThreshold | int | `5` | Min consecutive failures for the probe to be considered failed | +| livenessProbe.initialDelaySeconds | int | `60` | Delay before the probe is initiated | +| livenessProbe.periodSeconds | int | `10` | How often to perform the probe | +| livenessProbe.successThreshold | int | `1` | Min consecutive success for the probe to be considered successful | +| livenessProbe.timeoutSeconds | int | `5` | When the probe times out | +| logLevel | string | `"WARN"` | Default log level, use either one of `DEBUG`, `INFO`, `WARN` or `ERROR` | +| logType | string | `"Console"` | Log format, either `JSON` or `Console` | +| nodeSelector | object | `{}` | Node labels for pod assignment | +| postgresql.existingSecret | string | `nil` | Existing secret to use for authenticating to Postgres | +| prometheus.enabled | bool | `true` | Flag to enable scraping of Feast Core metrics | +| readinessProbe.enabled | bool | `true` | Flag to enabled the probe | +| readinessProbe.failureThreshold | int | `5` | Min consecutive failures for the probe to be considered failed | +| readinessProbe.initialDelaySeconds | int | `20` | Delay before the probe is initiated | +| readinessProbe.periodSeconds | int | `10` | How often to perform the probe | +| readinessProbe.successThreshold | int | `1` | Min consecutive success for the probe to be considered successful | +| readinessProbe.timeoutSeconds | int | `10` | When the probe times out | +| replicaCount | int | `1` | Number of pods that will be created | +| resources | object | `{}` | CPU/memory [resource requests/limit](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container) | +| service.grpc.nodePort | string | `nil` | Port number that each cluster node will listen to | +| service.grpc.port | int | `6565` | Service port for GRPC requests | +| service.grpc.targetPort | int | `6565` | Container port serving GRPC requests | +| service.http.nodePort | string | `nil` | Port number that each cluster node will listen to | +| service.http.port | int | `80` | Service port for HTTP requests | +| service.http.targetPort | int | `8080` | Container port serving HTTP requests | +| service.type | string | `"ClusterIP"` | Kubernetes service type | diff --git a/infra/charts/feast/charts/feast-core/charts/kafka-0.20.1.tgz b/infra/charts/feast/charts/feast-core/charts/kafka-0.20.1.tgz deleted file mode 100644 index 76a2247577d43a5c7b7da189eab9ca2bb90e30ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30761 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

Aw_*qVAg6yrgW?!PQ^G`vMO~SRR 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

pjz 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 diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/README.md b/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/README.md deleted file mode 100644 index 69eb33039b8..00000000000 --- a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Prometheus statsd-exporter - - ## TL;DR; - - ```console -$ helm install incubator/prometheus-statsd-exporter -``` - - ## Introduction - - This chart bootstraps a prometheus-statsd-exporter deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - - ## Installing the Chart - - To install the chart with the release name `my-release`: - - ```console -$ helm install incubator/prometheus-statsd-exporter --name my-release -``` - - - The command deploys prometheus-statsd-exporter on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. - - ## Uninstalling the Chart - - To uninstall/delete the `my-release` deployment: - - ```console -$ helm delete my-release -``` - - The command removes all the Kubernetes components associated with the chart and deletes the release. - - ## Configuration - - |Parameter | Description | Default | -|`extraArgs` | key:value list of extra arguments to give the binary | `{}` | -|`image.pullPolicy` | Image pull policy | `IfNotPresent` | -|`image.repository` | Image repository | `prom/statsd-exporter` | -|`image.tag` | Image tag | `v0.8.0` | -|`ingress.enabled` | enable ingress | `false` | -|`ingress.path` | ingress base path | `/` | -|`ingress.host` | Ingress accepted hostnames | `nil` | -|`ingress.tls` | Ingress TLS configuration | `[]` | -|`ingress.annotations` | Ingress annotations | `{}` | -|`service.type` | type of service | `ClusterIP` | -|`tolerations` | List of node taints to tolerate | `[]` | -|`resources` | pod resource requests & limits | `{}` | -| `persistence.enabled` | Create a volume to store data | true | - - Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, - - ```console -$ helm install incubator/prometheus-statsd-exporter --name my-release -f values.yaml -``` -> **Tip**: You can use the default [values.yaml](values.yaml) \ No newline at end of file diff --git a/infra/charts/feast/charts/feast-core/requirements.yaml b/infra/charts/feast/charts/feast-core/requirements.yaml deleted file mode 100644 index ef1e39a7d0f..00000000000 --- a/infra/charts/feast/charts/feast-core/requirements.yaml +++ /dev/null @@ -1,15 +0,0 @@ -dependencies: -- name: postgresql - version: 6.5.5 - repository: "@stable" - condition: postgresql.enabled -- name: kafka - version: 0.20.1 - repository: "@incubator" - condition: kafka.enabled -- name: common - version: 0.0.5 - repository: "@incubator" -- name: prometheus-statsd-exporter - version: 0.1.2 - condition: prometheus-statsd-exporter.enabled \ No newline at end of file diff --git a/infra/charts/feast/charts/feast-core/templates/configmap.yaml b/infra/charts/feast/charts/feast-core/templates/configmap.yaml index da45cad5bdf..2bcaa8c8b37 100644 --- a/infra/charts/feast/charts/feast-core/templates/configmap.yaml +++ b/infra/charts/feast/charts/feast-core/templates/configmap.yaml @@ -10,44 +10,27 @@ metadata: release: {{ .Release.Name }} heritage: {{ .Release.Service }} data: - application.yaml: | -{{- toYaml (index .Values "application.yaml") | nindent 4 }} - -{{- if .Values.postgresql.enabled }} - application-bundled-postgresql.yaml: | + application-default-postgresql.yaml: | spring: datasource: - url: {{ printf "jdbc:postgresql://%s:%s/%s" (printf "%s-postgresql" .Release.Name) (.Values.postgresql.service.port | toString) (.Values.postgresql.postgresqlDatabase) }} - driverClassName: org.postgresql.Driver -{{- end }} + url: jdbc:postgresql://{{ .Release.Name }}-postgresql:5432/postgres -{{ if .Values.kafka.enabled }} - {{- $topic := index .Values.kafka.topics 0 }} - application-bundled-kafka.yaml: | + application-default-kafka.yaml: | feast: stream: type: kafka - options: - topic: {{ $topic.name | quote }} - replicationFactor: {{ $topic.replicationFactor }} - partitions: {{ $topic.partitions }} - {{- if not .Values.kafka.external.enabled }} - bootstrapServers: {{ printf "%s:9092" (printf "%s-kafka" .Release.Name) }} - {{- end }} -{{- end }} + options: + bootstrapServers: {{ .Release.Name }}-kafka:9092 + topic: feast -{{- if (index .Values "prometheus-statsd-exporter" "enabled" )}} - application-bundled-statsd.yaml: | + application-default-statsd.yaml: | feast: jobs: metrics: - enabled: true + enabled: true type: statsd - host: prometheus-statsd-exporter + host: {{ .Release.Name }}-prometheus-statsd-exporter-udp port: 9125 -{{- end }} -{{- range $name, $content := .Values.springConfigProfiles }} - application-{{ $name }}.yaml: | -{{- toYaml $content | nindent 4 }} -{{- end }} + application-override.yaml: | +{{- toYaml (index .Values "application-override.yaml") | nindent 4 }} diff --git a/infra/charts/feast/charts/feast-core/templates/deployment.yaml b/infra/charts/feast/charts/feast-core/templates/deployment.yaml index df834b6749e..70d60cd89b7 100644 --- a/infra/charts/feast/charts/feast-core/templates/deployment.yaml +++ b/infra/charts/feast/charts/feast-core/templates/deployment.yaml @@ -20,9 +20,8 @@ spec: metadata: {{- if .Values.prometheus.enabled }} annotations: - {{ $config := index .Values "application.yaml" }} prometheus.io/path: /metrics - prometheus.io/port: "{{ $config.server.port }}" + prometheus.io/port: "8080" prometheus.io/scrape: "true" {{- end }} labels: @@ -39,23 +38,23 @@ spec: - name: {{ template "feast-core.fullname" . }}-config configMap: name: {{ template "feast-core.fullname" . }} - {{- if .Values.gcpServiceAccount.useExistingSecret }} - - name: {{ template "feast-core.fullname" . }}-gcpserviceaccount + {{- if .Values.gcpServiceAccount.enabled }} + - name: {{ template "feast-core.fullname" . }}-gcp-service-account secret: secretName: {{ .Values.gcpServiceAccount.existingSecret.name }} {{- end }} containers: - name: {{ .Chart.Name }} - image: '{{ .Values.image.repository }}:{{ required "No .image.tag found. This must be provided as input." .Values.image.tag }}' + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} volumeMounts: - name: {{ template "feast-core.fullname" . }}-config - mountPath: "{{ .Values.springConfigMountPath }}" - {{- if .Values.gcpServiceAccount.useExistingSecret }} - - name: {{ template "feast-core.fullname" . }}-gcpserviceaccount - mountPath: {{ .Values.gcpServiceAccount.mountPath }} + mountPath: /etc/feast + {{- if .Values.gcpServiceAccount.enabled }} + - name: {{ template "feast-core.fullname" . }}-gcp-service-account + mountPath: /etc/secrets/google readOnly: true {{- end }} @@ -64,40 +63,32 @@ spec: value: {{ .Values.logType | quote }} - name: LOG_LEVEL value: {{ .Values.logLevel | quote }} - - {{- if .Values.postgresql.enabled }} - - name: SPRING_DATASOURCE_USERNAME - value: {{ .Values.postgresql.postgresqlUsername | quote }} - name: SPRING_DATASOURCE_PASSWORD - value: {{ .Values.postgresql.postgresqlPassword | quote }} - {{- end }} + valueFrom: + secretKeyRef: + name: {{ .Values.postgresql.existingSecret | default (printf "%s-postgresql" .Release.Name) }} + key: postgresql-password - {{- if .Values.gcpServiceAccount.useExistingSecret }} + {{- if .Values.gcpServiceAccount.enabled }} - name: GOOGLE_APPLICATION_CREDENTIALS - value: {{ .Values.gcpServiceAccount.mountPath }}/{{ .Values.gcpServiceAccount.existingSecret.key }} + value: /etc/secrets/google/{{ .Values.gcpServiceAccount.existingSecret.key }} {{- end }} + {{- if .Values.gcpProjectId }} - name: GOOGLE_CLOUD_PROJECT value: {{ .Values.gcpProjectId | quote }} {{- end }} - command: - - java - {{- range .Values.jvmOptions }} - - {{ . | quote }} - {{- end }} - - -jar - - {{ .Values.jarPath | quote }} - - "--spring.config.location=file:{{ .Values.springConfigMountPath }}/" - {{- $profilesArray := splitList "," .Values.springConfigProfilesActive -}} - {{- $profilesArray = append $profilesArray (.Values.postgresql.enabled | ternary "bundled-postgresql" "") -}} - {{- $profilesArray = append $profilesArray (.Values.kafka.enabled | ternary "bundled-kafka" "") -}} - {{- $profilesArray = append $profilesArray (index .Values "prometheus-statsd-exporter" "enabled" | ternary "bundled-statsd" "") -}} - {{- $profilesArray = compact $profilesArray -}} - {{- if $profilesArray }} - - "--spring.profiles.active={{ join "," $profilesArray }}" + {{- if .Values.javaOpts }} + - name: JAVA_OPTS + value: {{ .Values.javaOpts }} {{- end }} + command: + - java + - -jar + - /opt/feast/feast-core.jar + - --spring.config.additional-location=/etc/feast/application-default-postgresql.yaml,/etc/feast/application-default-kafka.yaml,/etc/feast/application-default-statsd.yaml,/etc/feast/application-override.yaml ports: - name: http containerPort: {{ .Values.service.http.targetPort }} diff --git a/infra/charts/feast/charts/feast-core/values.yaml b/infra/charts/feast/charts/feast-core/values.yaml index 077906dc35d..a2c3f2d00af 100644 --- a/infra/charts/feast/charts/feast-core/values.yaml +++ b/infra/charts/feast/charts/feast-core/values.yaml @@ -1,246 +1,132 @@ -# ============================================================ -# Bundled PostgreSQL -# ============================================================ - -# Refer to https://github.com/helm/charts/tree/c42002a21abf8eff839ff1d2382152bde2bbe596/stable/postgresql -# for additional configuration. -postgresql: - # enabled specifies whether Postgresql should be installed as part of Feast Core. - # - # Feast Core requires a database to store data such as the created FeatureSets - # and job statuses. If enabled, the database and service port specified below - # will override "spring.datasource.url" value in application.yaml. The - # username and password will also be set as environment variables that will - # override "spring.datasource.username/password" in application.yaml. - enabled: true - # postgresqlDatabase is the name of the database used by Feast Core. - postgresqlDatabase: feast - # postgresqlUsername is the username to authenticate to the database. - postgresqlUsername: postgres - # postgresqlPassword is the password to authenticate to the database. - postgresqlPassword: password - service: - # port is the TCP port that Postgresql will listen to - port: 5432 - -# ============================================================ -# Bundled Kafka -# ============================================================ - -# Refer to https://github.com/helm/charts/tree/c42002a21abf8eff839ff1d2382152bde2bbe596/incubator/kafka -# for additional configuration. -kafka: - # enabled specifies whether Kafka should be installed as part of Feast Core. - # - # Feast Core requires a Kafka instance to be set as the default source for - # FeatureRows. If enabled, "feast.stream" option in application.yaml will - # be overridden by this installed Kafka configuration. - enabled: true - topics: - # topic that will be used as default in Feast Core for the default Kafka source. - - name: feast - replicationFactor: 1 - partitions: 1 - - -# ============================================================ -# Bundled Prometheus StatsD Exporter -# ============================================================ - -prometheus-statsd-exporter: - enabled: false - -# ============================================================ -# Feast Core -# ============================================================ - -# replicaCount is the number of pods that will be created. +# replicaCount -- Number of pods that will be created replicaCount: 1 -# image configures the Docker image for Feast Core image: + # image.repository -- Docker image repository repository: gcr.io/kf-feast/feast-core + # image.tag -- Image tag + tag: 0.4.6 + # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent -# Add prometheus scraping annotations to the Pod metadata. -# If enabled, you must also ensure server.port is specified under application.yaml -prometheus: - enabled: false - -# application.yaml is the main configuration for Feast Core application. -# -# Feast Core is a Spring Boot app which uses this yaml configuration file. -# Refer to https://github.com/gojek/feast/blob/79eb4ab5fa3d37102c1dca9968162a98690526ba/core/src/main/resources/application.yml -# for a complete list and description of the configuration. -# -# Note that some properties defined in application.yaml may be overriden by -# Helm under certain conditions. For example, if postgresql and kafka dependencies -# are enabled. -application.yaml: - grpc: - port: 6565 - enable-reflection: true - feast: - jobs: - runner: DirectRunner - options: {} - updates: - timeoutSeconds: 240 - metrics: - enabled: false - type: statsd - host: localhost - port: 9125 - stream: - type: kafka - options: - topic: TOPIC - bootstrapServers: HOST:PORT - replicationFactor: 1 - partitions: 1 - spring: - jpa: - properties.hibernate.format_sql: true - properties.hibernate.event.merge.entity_copy_observer: allow - hibernate.naming.physical-strategy=org.hibernate.boot.model.naming: PhysicalNamingStrategyStandardImpl - hibernate.ddl-auto: update - datasource: - driverClassName: org.postgresql.Driver - url: jdbc:postgresql://HOST:PORT/DATABASE - username: USERNAME - password: PASSWORD - management: - metrics: - export: - simple: - enabled: false - statsd: - enabled: false - host: localhost - port: 8125 - -springConfigProfiles: {} -# db: | -# spring: -# datasource: -# driverClassName: org.postgresql.Driver -# url: jdbc:postgresql://${DB_HOST:127.0.0.1}:${DB_PORT:5432}/${DB_DATABASE:postgres} -springConfigProfilesActive: "" -# springConfigMountPath is the directory path where application.yaml will be -# mounted in the container. -springConfigMountPath: /etc/feast/feast-core +# "application-override.yaml" -- [Configuration override](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml) for Feast Core +application-override.yaml: {} -# gcpServiceAccount is the service account that Feast Core will use. gcpServiceAccount: - # useExistingSecret specifies Feast to use an existing secret containing Google - # Cloud service account JSON key file. - useExistingSecret: false + # gcpServiceAccount.enabled -- Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key + enabled: false existingSecret: - # name is the secret name of the existing secret for the service account. + # gcpServiceAccount.existingSecret.name -- Name of the existing secret containing the service account name: feast-gcp-service-account - # key is the secret key of the existing secret for the service account. - # key is normally derived from the file name of the JSON key file. - key: key.json - # mountPath is the directory path where the JSON key file will be mounted. - # the value of "existingSecret.key" is file name of the service account file. - mountPath: /etc/gcloud/service-accounts + # gcpServiceAccount.existingSecret.key -- Key in the secret data (file name of the service account) + key: credentials.json -# Project ID picked up by the Cloud SDK (e.g. BigQuery run against this project) -gcpProjectId: "" +postgresql: + # postgresql.existingSecret -- Existing secret to use for authenticating to Postgres + existingSecret: -# Path to Jar file in the Docker image. -# If you are using gcr.io/kf-feast/feast-core this should not need to be changed -jarPath: /opt/feast/feast-core.jar +# javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). It is advised for better performance to set the min and max heap:
`-Xms2048m -Xmx2048m` +javaOpts: -# jvmOptions are options that will be passed to the Java Virtual Machine (JVM) -# running Feast Core. -# -# For example, it is good practice to set min and max heap size in JVM. -# https://stackoverflow.com/questions/6902135/side-effect-for-increasing-maxpermsize-and-max-heap-size -# -# Refer to https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html -# to see other JVM options that can be set. -# -jvmOptions: [] -# - -Xms1024m -# - -Xmx1024m +# logType -- Log format, either `JSON` or `Console` +logType: Console +# logLevel -- Default log level, use either one of `DEBUG`, `INFO`, `WARN` or `ERROR` +logLevel: WARN -logType: JSON -logLevel: warn +prometheus: + # prometheus.enabled -- Flag to enable scraping of Feast Core metrics + enabled: true livenessProbe: + # livenessProbe.enabled -- Flag to enabled the probe enabled: true + # livenessProbe.initialDelaySeconds -- Delay before the probe is initiated initialDelaySeconds: 60 + # livenessProbe.periodSeconds -- How often to perform the probe periodSeconds: 10 + # livenessProbe.timeoutSeconds -- When the probe times out timeoutSeconds: 5 + # livenessProbe.successThreshold -- Min consecutive success for the probe to be considered successful successThreshold: 1 + # livenessProbe.failureThreshold -- Min consecutive failures for the probe to be considered failed failureThreshold: 5 readinessProbe: + # readinessProbe.enabled -- Flag to enabled the probe enabled: true - initialDelaySeconds: 15 + # readinessProbe.initialDelaySeconds -- Delay before the probe is initiated + initialDelaySeconds: 20 + # readinessProbe.periodSeconds -- How often to perform the probe periodSeconds: 10 + # readinessProbe.timeoutSeconds -- When the probe times out timeoutSeconds: 10 + # readinessProbe.successThreshold -- Min consecutive success for the probe to be considered successful successThreshold: 1 + # readinessProbe.failureThreshold -- Min consecutive failures for the probe to be considered failed failureThreshold: 5 service: + # service.type -- Kubernetes service type type: ClusterIP http: + # service.http.port -- Service port for HTTP requests port: 80 + # service.http.targetPort -- Container port serving HTTP requests targetPort: 8080 - # nodePort is the port number that each cluster node will listen to - # https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - # - # nodePort: + # service.http.nodePort -- Port number that each cluster node will listen to + nodePort: grpc: + # service.grpc.port -- Service port for GRPC requests port: 6565 + # service.grpc.targetPort -- Container port serving GRPC requests targetPort: 6565 - # nodePort is the port number that each cluster node will listen to - # https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - # - # nodePort: + # service.grpc.nodePort -- Port number that each cluster node will listen to + nodePort: ingress: grpc: + # ingress.grpc.enabled -- Flag to create an ingress resource for the service enabled: false + # ingress.grpc.class -- Which ingress controller to use class: nginx + # ingress.grpc.hosts -- List of hostnames to match when routing requests hosts: [] + # ingress.grpc.annotations -- Extra annotations for the ingress annotations: {} https: + # ingress.grpc.https.enabled -- Flag to enable HTTPS enabled: true + # ingress.grpc.https.secretNames -- Map of hostname to TLS secret name secretNames: {} + # ingress.grpc.whitelist -- Allowed client IP source ranges whitelist: "" auth: + # ingress.grpc.auth.enabled -- Flag to enable auth enabled: false http: + # ingress.http.enabled -- Flag to create an ingress resource for the service enabled: false + # ingress.http.class -- Which ingress controller to use class: nginx + # ingress.http.hosts -- List of hostnames to match when routing requests hosts: [] + # ingress.http.annotations -- Extra annotations for the ingress annotations: {} https: + # ingress.http.https.enabled -- Flag to enable HTTPS enabled: true + # ingress.http.https.secretNames -- Map of hostname to TLS secret name secretNames: {} + # ingress.http.whitelist -- Allowed client IP source ranges whitelist: "" auth: + # ingress.http.auth.enabled -- Flag to enable auth enabled: false + # ingress.http.auth.authUrl -- URL to an existing authentication service authUrl: http://auth-server.auth-ns.svc.cluster.local/auth +# resources -- CPU/memory [resource requests/limit](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container) 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 labels for pod assignment nodeSelector: {} - -tolerations: [] - -affinity: {} diff --git a/infra/charts/feast/charts/feast-serving/Chart.yaml b/infra/charts/feast/charts/feast-serving/Chart.yaml index 2e9cf89243d..f7e526e57d7 100644 --- a/infra/charts/feast/charts/feast-serving/Chart.yaml +++ b/infra/charts/feast/charts/feast-serving/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 -description: A Helm chart for serving component of Feast +description: Feast Serving serves low-latency latest features and historical batch features. name: feast-serving -version: 0.4.4 +version: 0.4.6 diff --git a/infra/charts/feast/charts/feast-serving/README.md b/infra/charts/feast/charts/feast-serving/README.md new file mode 100644 index 00000000000..99b0e783874 --- /dev/null +++ b/infra/charts/feast/charts/feast-serving/README.md @@ -0,0 +1,65 @@ +feast-serving +============= +Feast Serving serves low-latency latest features and historical batch features. + +Current chart version is `0.4.6` + + + + + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| "application-override.yaml" | object | `{}` | [Configuration override](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml) for Feast Serving. Note that setting `store.config-path` is not necessary since this chart will set it to where `store.yaml` is mounted. | +| "store.yaml" | object | `{}` | Store [config](https://github.com/gojek/feast/blob/master/protos/feast/core/Store.proto#L32) in yaml format. This is an [example](https://github.com/gojek/feast/blob/v0.4-branch/serving/sample_redis_config.yml) for Redis. | +| gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | +| gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | +| gcpServiceAccount.existingSecret.name | string | `"feast-gcp-service-account"` | Name of the existing secret containing the service account | +| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | +| image.repository | string | `"gcr.io/kf-feast/feast-serving"` | Docker image repository | +| image.tag | string | `"0.4.6"` | Image tag | +| ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | +| ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | +| ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | +| ingress.grpc.enabled | bool | `false` | Flag to create an ingress resource for the service | +| ingress.grpc.hosts | list | `[]` | List of hostnames to match when routing requests | +| ingress.grpc.https.enabled | bool | `true` | Flag to enable HTTPS | +| ingress.grpc.https.secretNames | object | `{}` | Map of hostname to TLS secret name | +| ingress.grpc.whitelist | string | `""` | Allowed client IP source ranges | +| ingress.http.annotations | object | `{}` | Extra annotations for the ingress | +| ingress.http.auth.authUrl | string | `"http://auth-server.auth-ns.svc.cluster.local/auth"` | URL to an existing authentication service | +| ingress.http.auth.enabled | bool | `false` | Flag to enable auth | +| ingress.http.class | string | `"nginx"` | Which ingress controller to use | +| ingress.http.enabled | bool | `false` | Flag to create an ingress resource for the service | +| ingress.http.hosts | list | `[]` | List of hostnames to match when routing requests | +| ingress.http.https.enabled | bool | `true` | Flag to enable HTTPS | +| ingress.http.https.secretNames | object | `{}` | Map of hostname to TLS secret name | +| ingress.http.whitelist | string | `""` | Allowed client IP source ranges | +| javaOpts | string | `nil` | [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). It is advised for better performance to set the min and max heap:
`-Xms2048m -Xmx2048m` | +| livenessProbe.enabled | bool | `true` | Flag to enabled the probe | +| livenessProbe.failureThreshold | int | `5` | Min consecutive failures for the probe to be considered failed | +| livenessProbe.initialDelaySeconds | int | `60` | Delay before the probe is initiated | +| livenessProbe.periodSeconds | int | `10` | How often to perform the probe | +| livenessProbe.successThreshold | int | `1` | Min consecutive success for the probe to be considered successful | +| livenessProbe.timeoutSeconds | int | `5` | When the probe times out | +| logLevel | string | `"WARN"` | Default log level, use either one of `DEBUG`, `INFO`, `WARN` or `ERROR` | +| logType | string | `"Console"` | Log format, either `JSON` or `Console` | +| nodeSelector | object | `{}` | Node labels for pod assignment | +| prometheus.enabled | bool | `true` | Flag to enable scraping of Feast Core metrics | +| readinessProbe.enabled | bool | `true` | Flag to enabled the probe | +| readinessProbe.failureThreshold | int | `5` | Min consecutive failures for the probe to be considered failed | +| readinessProbe.initialDelaySeconds | int | `15` | Delay before the probe is initiated | +| readinessProbe.periodSeconds | int | `10` | How often to perform the probe | +| readinessProbe.successThreshold | int | `1` | Min consecutive success for the probe to be considered successful | +| readinessProbe.timeoutSeconds | int | `10` | When the probe times out | +| replicaCount | int | `1` | Number of pods that will be created | +| resources | object | `{}` | CPU/memory [resource requests/limit](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container) | +| service.grpc.nodePort | string | `nil` | Port number that each cluster node will listen to | +| service.grpc.port | int | `6566` | Service port for GRPC requests | +| service.grpc.targetPort | int | `6566` | Container port serving GRPC requests | +| service.http.nodePort | string | `nil` | Port number that each cluster node will listen to | +| service.http.port | int | `80` | Service port for HTTP requests | +| service.http.targetPort | int | `8080` | Container port serving HTTP requests | +| service.type | string | `"ClusterIP"` | Kubernetes service type | diff --git a/infra/charts/feast/charts/feast-serving/charts/redis-9.5.0.tgz b/infra/charts/feast/charts/feast-serving/charts/redis-9.5.0.tgz deleted file mode 100644 index 962893a825d6723e5831ad5528d82c00caaa57f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27574 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 CvqJg+ diff --git a/infra/charts/feast/charts/feast-serving/requirements.yaml b/infra/charts/feast/charts/feast-serving/requirements.yaml deleted file mode 100644 index 2cee3f81494..00000000000 --- a/infra/charts/feast/charts/feast-serving/requirements.yaml +++ /dev/null @@ -1,8 +0,0 @@ -dependencies: -- name: redis - version: 9.5.0 - repository: "@stable" - condition: redis.enabled -- name: common - version: 0.0.5 - repository: "@incubator" diff --git a/infra/charts/feast/charts/feast-serving/templates/configmap.yaml b/infra/charts/feast/charts/feast-serving/templates/configmap.yaml index 934216a9d5f..3dbcc192da2 100644 --- a/infra/charts/feast/charts/feast-serving/templates/configmap.yaml +++ b/infra/charts/feast/charts/feast-serving/templates/configmap.yaml @@ -10,44 +10,31 @@ metadata: release: {{ .Release.Name }} heritage: {{ .Release.Service }} data: - application.yaml: | -{{- toYaml (index .Values "application.yaml") | nindent 4 }} - -{{- if .Values.core.enabled }} - application-bundled-core.yaml: | - feast: - core-host: {{ printf "%s-feast-core" .Release.Name }} + store.yaml: | +{{- if index .Values "store.yaml" }} +{{- toYaml (index .Values "store.yaml") | nindent 4 }} +{{- else }} + name: redis-store + type: REDIS + redis_config: + host: {{ .Release.Name }}-redis-master + port: 6379 + subscriptions: + - name: "*" + project: "*" + version: "*" {{- end }} -{{- if eq (include "bq_store_and_no_job_options" .) "true" }} - application-bundled-redis.yaml: | + application-default.yaml: | feast: + core-host: {{ .Release.Name }}-feast-core + store: + config-path: /etc/feast/store.yaml jobs: + store-type: REDIS store-options: - host: {{ printf "%s-redis-headless" .Release.Name }} + host: {{ .Release.Name }}-redis-master port: 6379 -{{- end }} - store.yaml: | -{{- $store := index .Values "store.yaml"}} - -{{- if and .Values.redis.enabled (eq $store.type "REDIS") }} - -{{- if eq .Values.redis.master.service.type "ClusterIP" }} -{{- $newConfig := dict "redis_config" (dict "host" (printf "%s-redis-headless" .Release.Name) "port" .Values.redis.redisPort) }} -{{- $config := mergeOverwrite $store $newConfig }} -{{- end }} - -{{- if and (eq .Values.redis.master.service.type "LoadBalancer") (not (empty .Values.redis.master.service.loadBalancerIP)) }} -{{- $newConfig := dict "redis_config" (dict "host" .Values.redis.master.service.loadBalancerIP "port" .Values.redis.redisPort) }} -{{- $config := mergeOverwrite $store $newConfig }} -{{- end }} - -{{- end }} - -{{- toYaml $store | nindent 4 }} - -{{- range $name, $content := .Values.springConfigProfiles }} - application-{{ $name }}.yaml: | -{{- toYaml $content | nindent 4 }} -{{- end }} + application-override.yaml: | +{{- toYaml (index .Values "application-override.yaml") | nindent 4 }} diff --git a/infra/charts/feast/charts/feast-serving/templates/deployment.yaml b/infra/charts/feast/charts/feast-serving/templates/deployment.yaml index 64dd3955d0c..9930ac441d0 100644 --- a/infra/charts/feast/charts/feast-serving/templates/deployment.yaml +++ b/infra/charts/feast/charts/feast-serving/templates/deployment.yaml @@ -20,9 +20,8 @@ spec: metadata: annotations: {{- if .Values.prometheus.enabled }} - {{ $config := index .Values "application.yaml" }} prometheus.io/path: /metrics - prometheus.io/port: "{{ $config.server.port }}" + prometheus.io/port: "8080" prometheus.io/scrape: "true" {{- end }} labels: @@ -39,23 +38,23 @@ spec: - name: {{ template "feast-serving.fullname" . }}-config configMap: name: {{ template "feast-serving.fullname" . }} - {{- if .Values.gcpServiceAccount.useExistingSecret }} - - name: {{ template "feast-serving.fullname" . }}-gcpserviceaccount + {{- if .Values.gcpServiceAccount.enabled }} + - name: {{ template "feast-serving.fullname" . }}-gcp-service-account secret: secretName: {{ .Values.gcpServiceAccount.existingSecret.name }} {{- end }} containers: - name: {{ .Chart.Name }} - image: '{{ .Values.image.repository }}:{{ required "No .image.tag found. This must be provided as input." .Values.image.tag }}' + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} volumeMounts: - name: {{ template "feast-serving.fullname" . }}-config - mountPath: "{{ .Values.springConfigMountPath }}" - {{- if .Values.gcpServiceAccount.useExistingSecret }} - - name: {{ template "feast-serving.fullname" . }}-gcpserviceaccount - mountPath: {{ .Values.gcpServiceAccount.mountPath }} + mountPath: /etc/feast + {{- if .Values.gcpServiceAccount.enabled }} + - name: {{ template "feast-serving.fullname" . }}-gcp-service-account + mountPath: /etc/secrets/google readOnly: true {{- end }} @@ -65,30 +64,26 @@ spec: - name: LOG_LEVEL value: {{ .Values.logLevel | quote }} - {{- if .Values.gcpServiceAccount.useExistingSecret }} + {{- if .Values.gcpServiceAccount.enabled }} - name: GOOGLE_APPLICATION_CREDENTIALS - value: {{ .Values.gcpServiceAccount.mountPath }}/{{ .Values.gcpServiceAccount.existingSecret.key }} + value: /etc/secrets/google/{{ .Values.gcpServiceAccount.existingSecret.key }} {{- end }} + {{- if .Values.gcpProjectId }} - name: GOOGLE_CLOUD_PROJECT value: {{ .Values.gcpProjectId | quote }} {{- end }} + {{- if .Values.javaOpts }} + - name: JAVA_OPTS + value: {{ .Values.javaOpts }} + {{- end }} + command: - java - {{- range .Values.jvmOptions }} - - {{ . | quote }} - {{- end }} - -jar - - {{ .Values.jarPath | quote }} - - "--spring.config.location=file:{{ .Values.springConfigMountPath }}/" - {{- $profilesArray := splitList "," .Values.springConfigProfilesActive -}} - {{- $profilesArray = append $profilesArray (.Values.core.enabled | ternary "bundled-core" "") -}} - {{- $profilesArray = append $profilesArray (eq (include "bq_store_and_no_job_options" .) "true" | ternary "bundled-redis" "") -}} - {{- $profilesArray = compact $profilesArray -}} - {{- if $profilesArray }} - - "--spring.profiles.active={{ join "," $profilesArray }}" - {{- end }} + - /opt/feast/feast-serving.jar + - --spring.config.additional-location=/etc/feast/application-default.yaml,/etc/feast/application-override.yaml ports: - name: http diff --git a/infra/charts/feast/charts/feast-serving/values.yaml b/infra/charts/feast/charts/feast-serving/values.yaml index 52d10cd7440..9108e706abc 100644 --- a/infra/charts/feast/charts/feast-serving/values.yaml +++ b/infra/charts/feast/charts/feast-serving/values.yaml @@ -1,234 +1,132 @@ -# redis configures Redis that is installed as part of Feast Serving. -# Refer to https://github.com/helm/charts/tree/99430c4afdc88213c1ca08f40eeb03868ffcc9d7/stable/redis -# for additional configuration -redis: - # enabled specifies whether Redis should be installed as part of Feast Serving. - # - # If enabled, "redis_config" in store.yaml will be overwritten by Helm - # to the configuration in this Redis installation. - enabled: false - # usePassword specifies if password is required to access Redis. Note that - # Feast 0.3 does not support Redis with password. - usePassword: false - # cluster configuration for Redis. - cluster: - # enabled specifies if Redis should be installed in cluster mode. - enabled: false - -# core configures Feast Core in the same parent feast chart that this Feast -# Serving connects to. -core: - # enabled specifies that Feast Serving will use Feast Core installed - # in the same parent feast chart. If enabled, Helm will overwrite - # "feast.core-host" in application.yaml with the correct value. - enabled: true - -# replicaCount is the number of pods that will be created. +# replicaCount -- Number of pods that will be created replicaCount: 1 -# image configures the Docker image for Feast Serving image: + # image.repository -- Docker image repository repository: gcr.io/kf-feast/feast-serving + # image.tag -- Image tag + tag: 0.4.6 + # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent -# application.yaml is the main configuration for Feast Serving application. -# -# Feast Core is a Spring Boot app which uses this yaml configuration file. -# Refer to https://github.com/gojek/feast/blob/79eb4ab5fa3d37102c1dca9968162a98690526ba/serving/src/main/resources/application.yml -# for a complete list and description of the configuration. -# -# Note that some properties defined in application.yaml may be overridden by -# Helm under certain conditions. For example, if core is enabled, then -# "feast.core-host" will be overridden. Also, if "type: BIGQUERY" is specified -# in store.yaml, "feast.jobs.store-options" will be overridden as well with -# the default option supported in Feast 0.3. -application.yaml: - feast: - version: 0.3 - core-host: localhost - core-grpc-port: 6565 - tracing: - enabled: false - tracer-name: jaeger - service-name: feast-serving - store: - config-path: /etc/feast/feast-serving/store.yaml - redis-pool-max-size: 128 - redis-pool-max-idle: 64 - jobs: - staging-location: "" - store-type: "" - store-options: {} - grpc: - port: 6566 - enable-reflection: true - server: - port: 8080 - -# store.yaml is the configuration for Feast Store. -# -# Refer to this link for description: -# https://github.com/gojek/feast/blob/79eb4ab5fa3d37102c1dca9968162a98690526ba/protos/feast/core/Store.proto -# -# Use the correct store configuration depending on whether the installed -# Feast Serving is "online" or "batch", by uncommenting the correct store.yaml. -# -# Note that if "redis.enabled: true" and "type: REDIS" in store.yaml, -# Helm will override "redis_config" with configuration of Redis installed -# in this chart. -# -# Note that if "type: BIGQUERY" in store.yaml, Helm assumes Feast Online serving -# is also installed with Redis store. Helm will then override "feast.jobs.store-options" -# in application.yaml with the installed Redis store configuration. This is -# because in Feast 0.3, Redis job store is required. -# -# store.yaml: -# name: online -# type: REDIS -# redis_config: -# host: localhost -# port: 6379 -# subscriptions: -# - project: "*" -# name: "*" -# version: "*" -# -# store.yaml: -# name: bigquery -# type: BIGQUERY -# bigquery_config: -# project_id: PROJECT_ID -# dataset_id: DATASET_ID -# subscriptions: -# - project: "*" -# name: "*" -# version: "*" +# "store.yaml" -- Store [config](https://github.com/gojek/feast/blob/master/protos/feast/core/Store.proto#L32) in yaml format. This is an [example](https://github.com/gojek/feast/blob/v0.4-branch/serving/sample_redis_config.yml) for Redis. +store.yaml: {} -springConfigProfiles: {} -# db: | -# spring: -# datasource: -# driverClassName: org.postgresql.Driver -# url: jdbc:postgresql://${DB_HOST:127.0.0.1}:${DB_PORT:5432}/${DB_DATABASE:postgres} -springConfigProfilesActive: "" -# springConfigMountPath is the directory path where application.yaml and -# store.yaml will be mounted in the container. -springConfigMountPath: /etc/feast/feast-serving +# "application-override.yaml" -- [Configuration override](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml) for Feast Serving. Note that setting `store.config-path` is not necessary since this chart will set it to where `store.yaml` is mounted. +application-override.yaml: {} -# gcpServiceAccount is the service account that Feast Serving will use. gcpServiceAccount: - # useExistingSecret specifies Feast to use an existing secret containing Google + # gcpServiceAccount.enabled -- Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key # Cloud service account JSON key file. - useExistingSecret: false + enabled: false existingSecret: - # name is the secret name of the existing secret for the service account. + # gcpServiceAccount.existingSecret.name -- Name of the existing secret containing the service account name: feast-gcp-service-account - # key is the secret key of the existing secret for the service account. - # key is normally derived from the file name of the JSON key file. - key: key.json - # mountPath is the directory path where the JSON key file will be mounted. - # the value of "existingSecret.key" is file name of the service account file. - mountPath: /etc/gcloud/service-accounts - -# Project ID picked up by the Cloud SDK (e.g. BigQuery run against this project) -gcpProjectId: "" + # gcpServiceAccount.existingSecret.key -- Key in the secret data (file name of the service account) + key: credentials.json -# Path to Jar file in the Docker image. -# If using gcr.io/kf-feast/feast-serving this should not need to be changed. -jarPath: /opt/feast/feast-serving.jar +# javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). It is advised for better performance to set the min and max heap:
`-Xms2048m -Xmx2048m` +javaOpts: -# jvmOptions are options that will be passed to the Java Virtual Machine (JVM) -# running Feast Core. -# -# For example, it is good practice to set min and max heap size in JVM. -# https://stackoverflow.com/questions/6902135/side-effect-for-increasing-maxpermsize-and-max-heap-size -# -# Refer to https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html -# to see other JVM options that can be set. -# -jvmOptions: [] -# - -Xms768m -# - -Xmx768m +# logType -- Log format, either `JSON` or `Console` +logType: Console +# logLevel -- Default log level, use either one of `DEBUG`, `INFO`, `WARN` or `ERROR` +logLevel: WARN -logType: JSON -logLevel: warn +prometheus: + # prometheus.enabled -- Flag to enable scraping of Feast Core metrics + enabled: true livenessProbe: - enabled: false + # livenessProbe.enabled -- Flag to enabled the probe + enabled: true + # livenessProbe.initialDelaySeconds -- Delay before the probe is initiated initialDelaySeconds: 60 + # livenessProbe.periodSeconds -- How often to perform the probe periodSeconds: 10 + # livenessProbe.timeoutSeconds -- When the probe times out timeoutSeconds: 5 + # livenessProbe.successThreshold -- Min consecutive success for the probe to be considered successful successThreshold: 1 + # livenessProbe.failureThreshold -- Min consecutive failures for the probe to be considered failed failureThreshold: 5 readinessProbe: - enabled: false + # readinessProbe.enabled -- Flag to enabled the probe + enabled: true + # readinessProbe.initialDelaySeconds -- Delay before the probe is initiated initialDelaySeconds: 15 + # readinessProbe.periodSeconds -- How often to perform the probe periodSeconds: 10 + # readinessProbe.timeoutSeconds -- When the probe times out timeoutSeconds: 10 + # readinessProbe.successThreshold -- Min consecutive success for the probe to be considered successful successThreshold: 1 + # readinessProbe.failureThreshold -- Min consecutive failures for the probe to be considered failed failureThreshold: 5 service: + # service.type -- Kubernetes service type type: ClusterIP http: + # service.http.port -- Service port for HTTP requests port: 80 + # service.http.targetPort -- Container port serving HTTP requests targetPort: 8080 - # nodePort is the port number that each cluster node will listen to - # https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - # - # nodePort: + # service.http.nodePort -- Port number that each cluster node will listen to + nodePort: grpc: + # service.grpc.port -- Service port for GRPC requests port: 6566 + # service.grpc.targetPort -- Container port serving GRPC requests targetPort: 6566 - # nodePort is the port number that each cluster node will listen to - # https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - # - # nodePort: + # service.grpc.nodePort -- Port number that each cluster node will listen to + nodePort: ingress: grpc: + # ingress.grpc.enabled -- Flag to create an ingress resource for the service enabled: false + # ingress.grpc.class -- Which ingress controller to use class: nginx + # ingress.grpc.hosts -- List of hostnames to match when routing requests hosts: [] + # ingress.grpc.annotations -- Extra annotations for the ingress annotations: {} https: + # ingress.grpc.https.enabled -- Flag to enable HTTPS enabled: true + # ingress.grpc.https.secretNames -- Map of hostname to TLS secret name secretNames: {} + # ingress.grpc.whitelist -- Allowed client IP source ranges whitelist: "" auth: + # ingress.grpc.auth.enabled -- Flag to enable auth enabled: false http: + # ingress.http.enabled -- Flag to create an ingress resource for the service enabled: false + # ingress.http.class -- Which ingress controller to use class: nginx + # ingress.http.hosts -- List of hostnames to match when routing requests hosts: [] + # ingress.http.annotations -- Extra annotations for the ingress annotations: {} https: + # ingress.http.https.enabled -- Flag to enable HTTPS enabled: true + # ingress.http.https.secretNames -- Map of hostname to TLS secret name secretNames: {} + # ingress.http.whitelist -- Allowed client IP source ranges whitelist: "" auth: + # ingress.http.auth.enabled -- Flag to enable auth enabled: false + # ingress.http.auth.authUrl -- URL to an existing authentication service authUrl: http://auth-server.auth-ns.svc.cluster.local/auth -prometheus: - enabled: true - +# resources -- CPU/memory [resource requests/limit](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container) 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 labels for pod assignment nodeSelector: {} - -tolerations: [] - -affinity: {} diff --git a/infra/charts/feast/charts/grafana/.helmignore b/infra/charts/feast/charts/grafana/.helmignore new file mode 100644 index 00000000000..8cade1318fb --- /dev/null +++ b/infra/charts/feast/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/infra/charts/feast/charts/grafana/Chart.yaml b/infra/charts/feast/charts/grafana/Chart.yaml new file mode 100644 index 00000000000..b8d5e3eded4 --- /dev/null +++ b/infra/charts/feast/charts/grafana/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +name: grafana +version: 5.0.5 +appVersion: 6.6.2 +kubeVersion: "^1.8.0-0" +description: The leading tool for querying and visualizing time series and metrics. +home: https://grafana.net +icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png +sources: + - https://github.com/grafana/grafana +maintainers: + - name: zanhsieh + email: zanhsieh@gmail.com + - name: rtluckie + email: rluckie@cisco.com + - name: maorfr + email: maor.friedman@redhat.com +engine: gotpl +tillerVersion: ">=2.12.0" diff --git a/infra/charts/feast/charts/grafana/OWNERS b/infra/charts/feast/charts/grafana/OWNERS new file mode 100644 index 00000000000..29b8299822a --- /dev/null +++ b/infra/charts/feast/charts/grafana/OWNERS @@ -0,0 +1,8 @@ +approvers: +- zanhsieh +- rtluckie +- maorfr +reviewers: +- zanhsieh +- rtluckie +- maorfr diff --git a/infra/charts/feast/charts/grafana/README.md b/infra/charts/feast/charts/grafana/README.md new file mode 100644 index 00000000000..e50bb165d7b --- /dev/null +++ b/infra/charts/feast/charts/grafana/README.md @@ -0,0 +1,128 @@ +grafana +======= +The leading tool for querying and visualizing time series and metrics. + +Current chart version is `5.0.5` + +Source code can be found [here](https://grafana.net) + + + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| "grafana.ini".analytics.check_for_updates | bool | `true` | | +| "grafana.ini".grafana_net.url | string | `"https://grafana.net"` | | +| "grafana.ini".log.mode | string | `"console"` | | +| "grafana.ini".paths.data | string | `"/var/lib/grafana/data"` | | +| "grafana.ini".paths.logs | string | `"/var/log/grafana"` | | +| "grafana.ini".paths.plugins | string | `"/var/lib/grafana/plugins"` | | +| "grafana.ini".paths.provisioning | string | `"/etc/grafana/provisioning"` | | +| admin.existingSecret | string | `""` | | +| admin.passwordKey | string | `"admin-password"` | | +| admin.userKey | string | `"admin-user"` | | +| adminUser | string | `"admin"` | | +| affinity | object | `{}` | | +| dashboardProviders | object | `{}` | | +| dashboards | object | `{}` | | +| dashboardsConfigMaps | object | `{}` | | +| datasources | object | `{}` | | +| deploymentStrategy.type | string | `"RollingUpdate"` | | +| downloadDashboards.env | object | `{}` | | +| downloadDashboardsImage.pullPolicy | string | `"IfNotPresent"` | | +| downloadDashboardsImage.repository | string | `"curlimages/curl"` | | +| downloadDashboardsImage.tag | string | `"7.68.0"` | | +| env | object | `{}` | | +| envFromSecret | string | `""` | | +| envRenderSecret | object | `{}` | | +| envValueFrom | object | `{}` | | +| extraConfigmapMounts | list | `[]` | | +| extraContainers | string | `""` | | +| extraEmptyDirMounts | list | `[]` | | +| extraInitContainers | list | `[]` | | +| extraSecretMounts | list | `[]` | | +| extraVolumeMounts | list | `[]` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"grafana/grafana"` | | +| image.tag | string | `"6.6.2"` | | +| ingress.annotations | object | `{}` | | +| ingress.enabled | bool | `false` | | +| ingress.extraPaths | list | `[]` | | +| ingress.hosts[0] | string | `"chart-example.local"` | | +| ingress.labels | object | `{}` | | +| ingress.path | string | `"/"` | | +| ingress.tls | list | `[]` | | +| initChownData.enabled | bool | `true` | | +| initChownData.image.pullPolicy | string | `"IfNotPresent"` | | +| initChownData.image.repository | string | `"busybox"` | | +| initChownData.image.tag | string | `"1.31.1"` | | +| initChownData.resources | object | `{}` | | +| ldap.config | string | `""` | | +| ldap.enabled | bool | `false` | | +| ldap.existingSecret | string | `""` | | +| livenessProbe.failureThreshold | int | `10` | | +| livenessProbe.httpGet.path | string | `"/api/health"` | | +| livenessProbe.httpGet.port | int | `3000` | | +| livenessProbe.initialDelaySeconds | int | `60` | | +| livenessProbe.timeoutSeconds | int | `30` | | +| namespaceOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| notifiers | object | `{}` | | +| persistence.accessModes[0] | string | `"ReadWriteOnce"` | | +| persistence.enabled | bool | `false` | | +| persistence.finalizers[0] | string | `"kubernetes.io/pvc-protection"` | | +| persistence.size | string | `"10Gi"` | | +| persistence.type | string | `"pvc"` | | +| plugins | list | `[]` | | +| podDisruptionBudget | object | `{}` | | +| podPortName | string | `"grafana"` | | +| rbac.create | bool | `true` | | +| rbac.extraClusterRoleRules | list | `[]` | | +| rbac.extraRoleRules | list | `[]` | | +| rbac.namespaced | bool | `false` | | +| rbac.pspEnabled | bool | `true` | | +| rbac.pspUseAppArmor | bool | `true` | | +| readinessProbe.httpGet.path | string | `"/api/health"` | | +| readinessProbe.httpGet.port | int | `3000` | | +| replicas | int | `1` | | +| resources | object | `{}` | | +| securityContext.fsGroup | int | `472` | | +| securityContext.runAsUser | int | `472` | | +| service.annotations | object | `{}` | | +| service.labels | object | `{}` | | +| service.port | int | `80` | | +| service.portName | string | `"service"` | | +| service.targetPort | int | `3000` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `nil` | | +| serviceAccount.nameTest | string | `nil` | | +| sidecar.dashboards.SCProvider | bool | `true` | | +| sidecar.dashboards.defaultFolderName | string | `nil` | | +| sidecar.dashboards.enabled | bool | `false` | | +| sidecar.dashboards.folder | string | `"/tmp/dashboards"` | | +| sidecar.dashboards.label | string | `"grafana_dashboard"` | | +| sidecar.dashboards.provider.allowUiUpdates | bool | `false` | | +| sidecar.dashboards.provider.disableDelete | bool | `false` | | +| sidecar.dashboards.provider.folder | string | `""` | | +| sidecar.dashboards.provider.name | string | `"sidecarProvider"` | | +| sidecar.dashboards.provider.orgid | int | `1` | | +| sidecar.dashboards.provider.type | string | `"file"` | | +| sidecar.dashboards.searchNamespace | string | `nil` | | +| sidecar.dashboards.watchMethod | string | `"WATCH"` | | +| sidecar.datasources.enabled | bool | `false` | | +| sidecar.datasources.label | string | `"grafana_datasource"` | | +| sidecar.datasources.searchNamespace | string | `nil` | | +| sidecar.datasources.watchMethod | string | `"WATCH"` | | +| sidecar.image | string | `"kiwigrid/k8s-sidecar:0.1.99"` | | +| sidecar.imagePullPolicy | string | `"IfNotPresent"` | | +| sidecar.resources | object | `{}` | | +| smtp.existingSecret | string | `""` | | +| smtp.passwordKey | string | `"password"` | | +| smtp.userKey | string | `"user"` | | +| testFramework.enabled | bool | `true` | | +| testFramework.image | string | `"bats/bats"` | | +| testFramework.securityContext | object | `{}` | | +| testFramework.tag | string | `"v1.1.0"` | | +| tolerations | list | `[]` | | diff --git a/infra/charts/feast/charts/grafana/ci/default-values.yaml b/infra/charts/feast/charts/grafana/ci/default-values.yaml new file mode 100644 index 00000000000..fc2ba605ada --- /dev/null +++ b/infra/charts/feast/charts/grafana/ci/default-values.yaml @@ -0,0 +1 @@ +# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/infra/charts/feast/charts/grafana/ci/with-dashboard-json-values.yaml b/infra/charts/feast/charts/grafana/ci/with-dashboard-json-values.yaml new file mode 100644 index 00000000000..e0c4e41687a --- /dev/null +++ b/infra/charts/feast/charts/grafana/ci/with-dashboard-json-values.yaml @@ -0,0 +1,53 @@ +dashboards: + my-provider: + my-awesome-dashboard: + # An empty but valid dashboard + json: | + { + "__inputs": [], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "6.3.5" + } + ], + "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": null, + "links": [], + "panels": [], + "schemaVersion": 19, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": ["5s"] + }, + "timezone": "", + "title": "Dummy Dashboard", + "uid": "IdcYQooWk", + "version": 1 + } + datasource: Prometheus diff --git a/infra/charts/feast/charts/grafana/ci/with-dashboard-values.yaml b/infra/charts/feast/charts/grafana/ci/with-dashboard-values.yaml new file mode 100644 index 00000000000..7b662c5fd46 --- /dev/null +++ b/infra/charts/feast/charts/grafana/ci/with-dashboard-values.yaml @@ -0,0 +1,19 @@ +dashboards: + my-provider: + my-awesome-dashboard: + gnetId: 10000 + revision: 1 + datasource: Prometheus +dashboardProviders: + dashboardproviders.yaml: + apiVersion: 1 + providers: + - name: 'my-provider' + orgId: 1 + folder: '' + type: file + updateIntervalSeconds: 10 + disableDeletion: true + editable: true + options: + path: /var/lib/grafana/dashboards/my-provider diff --git a/infra/charts/feast/charts/grafana/dashboards/custom-dashboard.json b/infra/charts/feast/charts/grafana/dashboards/custom-dashboard.json new file mode 100644 index 00000000000..9e26dfeeb6e --- /dev/null +++ b/infra/charts/feast/charts/grafana/dashboards/custom-dashboard.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/infra/charts/feast/charts/grafana/templates/NOTES.txt b/infra/charts/feast/charts/grafana/templates/NOTES.txt new file mode 100644 index 00000000000..6e1436e9027 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/NOTES.txt @@ -0,0 +1,53 @@ +1. Get your '{{ .Values.adminUser }}' user password by running: + + kubectl get secret --namespace {{ template "grafana.namespace" . }} {{ template "grafana.fullname" . }} -o jsonpath="{.data.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: + + {{ template "grafana.fullname" . }}.{{ template "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 + 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 {{ template "grafana.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "grafana.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ template "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 {{ template "grafana.namespace" . }} -w {{ template "grafana.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ template "grafana.namespace" . }} {{ template "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 {{ template "grafana.namespace" . }} -l "app={{ template "grafana.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ template "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/infra/charts/feast/charts/grafana/templates/_helpers.tpl b/infra/charts/feast/charts/grafana/templates/_helpers.tpl new file mode 100644 index 00000000000..6b08bd1af43 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/_helpers.tpl @@ -0,0 +1,82 @@ +{{/* 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 .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "grafana.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} diff --git a/infra/charts/feast/charts/grafana/templates/_pod.tpl b/infra/charts/feast/charts/grafana/templates/_pod.tpl new file mode 100644 index 00000000000..e0e6e6fc584 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/_pod.tpl @@ -0,0 +1,369 @@ +{{- define "grafana.pod" -}} +{{- if .Values.schedulerName }} +schedulerName: "{{ .Values.schedulerName }}" +{{- end }} +serviceAccountName: {{ template "grafana.serviceAccountName" . }} +{{- if .Values.schedulerName }} +schedulerName: "{{ .Values.schedulerName }}" +{{- end }} +{{- if .Values.securityContext }} +securityContext: +{{ toYaml .Values.securityContext | indent 2 }} +{{- end }} +{{- if .Values.priorityClassName }} +priorityClassName: {{ .Values.priorityClassName }} +{{- end }} +{{- if ( or .Values.persistence.enabled .Values.dashboards .Values.extraInitContainers) }} +initContainers: +{{- end }} +{{- if ( and .Values.persistence.enabled .Values.initChownData.enabled ) }} + - name: init-chown-data + image: "{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}" + imagePullPolicy: {{ .Values.initChownData.image.pullPolicy }} + securityContext: + runAsUser: 0 + command: ["chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsUser }}", "/var/lib/grafana"] + resources: +{{ toYaml .Values.initChownData.resources | indent 6 }} + volumeMounts: + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} +{{- end }} +{{- end }} +{{- if .Values.dashboards }} + - name: download-dashboards + image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}" + imagePullPolicy: {{ .Values.downloadDashboardsImage.pullPolicy }} + command: ["/bin/sh"] + args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh /etc/grafana/download_dashboards.sh" ] + env: +{{- range $key, $value := .Values.downloadDashboards.env }} + - name: "{{ $key }}" + value: "{{ $value }}" +{{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/download_dashboards.sh" + subPath: download_dashboards.sh + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} +{{- end }} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- end }} +{{- end }} +{{- if .Values.extraInitContainers }} +{{ toYaml .Values.extraInitContainers | indent 2 }} +{{- end }} +{{- if .Values.image.pullSecrets }} +imagePullSecrets: +{{- range .Values.image.pullSecrets }} + - name: {{ . }} +{{- end}} +{{- end }} +containers: +{{- if .Values.sidecar.dashboards.enabled }} + - name: {{ template "grafana.name" . }}-sc-dashboard + image: "{{ .Values.sidecar.image }}" + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.dashboards.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.dashboards.label }}" + - name: FOLDER + value: "{{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}" + - name: RESOURCE + value: "both" + {{- if .Values.sidecar.dashboards.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.dashboards.searchNamespace }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} + volumeMounts: + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} +{{- end}} +{{- if .Values.sidecar.datasources.enabled }} + - name: {{ template "grafana.name" . }}-sc-datasources + image: "{{ .Values.sidecar.image }}" + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.datasources.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: "both" + {{- if .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.datasources.searchNamespace }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end}} + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.command }} + command: + {{- range .Values.command }} + - {{ . }} + {{- end }} + {{- 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: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} +{{- end }} +{{- if .Values.dashboards }} +{{- range $provider, $dashboards := .Values.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 -}} +{{- if .Values.dashboardsConfigMaps }} +{{- range (keys .Values.dashboardsConfigMaps | sortAlpha) }} + - name: dashboards-{{ . }} + mountPath: "/var/lib/grafana/dashboards/{{ . }}" +{{- end }} +{{- end }} +{{- if .Values.datasources }} + - name: config + mountPath: "/etc/grafana/provisioning/datasources/datasources.yaml" + subPath: datasources.yaml +{{- end }} +{{- if .Values.notifiers }} + - name: config + mountPath: "/etc/grafana/provisioning/notifiers/notifiers.yaml" + subPath: notifiers.yaml +{{- end }} +{{- if .Values.dashboardProviders }} + - name: config + mountPath: "/etc/grafana/provisioning/dashboards/dashboardproviders.yaml" + subPath: dashboardproviders.yaml +{{- 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}} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- 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.service.portName }} + containerPort: {{ .Values.service.port }} + protocol: TCP + - name: {{ .Values.podPortName }} + containerPort: 3000 + protocol: TCP + env: + {{- if not .Values.env.GF_SECURITY_ADMIN_USER }} + - name: GF_SECURITY_ADMIN_USER + valueFrom: + secretKeyRef: + name: {{ .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) }} + - name: GF_SECURITY_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .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: {{ template "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 }} + {{- range $key, $value := .Values.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: +{{ toYaml $value | indent 10 }} + {{- end }} +{{- range $key, $value := .Values.env }} + - name: "{{ $key }}" + value: "{{ $value }}" +{{- end }} + {{- if .Values.envFromSecret }} + envFrom: + - secretRef: + name: {{ .Values.envFromSecret }} + {{- end }} + {{- if .Values.envRenderSecret }} + envFrom: + - secretRef: + name: {{ template "grafana.fullname" . }}-env + {{- end }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 6 }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 6 }} + resources: +{{ toYaml .Values.resources | indent 6 }} +{{- with .Values.extraContainers }} +{{ tpl . $ | indent 2 }} +{{- end }} +{{- with .Values.nodeSelector }} +nodeSelector: +{{ toYaml . | indent 2 }} +{{- end }} +{{- with .Values.affinity }} +affinity: +{{ toYaml . | indent 2 }} +{{- end }} +{{- with .Values.tolerations }} +tolerations: +{{ toYaml . | indent 2 }} +{{- end }} +volumes: + - name: config + configMap: + name: {{ template "grafana.fullname" . }} +{{- range .Values.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} +{{- end }} + {{- if .Values.dashboards }} + {{- range (keys .Values.dashboards | sortAlpha) }} + - name: dashboards-{{ . }} + configMap: + name: {{ template "grafana.fullname" $ }}-dashboards-{{ . }} + {{- end }} + {{- end }} + {{- if .Values.dashboardsConfigMaps }} + {{ $root := . }} + {{- 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: {{ template "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: {{ .Values.persistence.existingClaim | default (include "grafana.fullname" .) }} +{{- else if and .Values.persistence.enabled (eq .Values.persistence.type "statefulset") }} +# nothing +{{- else }} + - name: storage + emptyDir: {} +{{- end -}} +{{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume + emptyDir: {} +{{- if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + configMap: + name: {{ template "grafana.fullname" . }}-config-dashboards +{{- end }} +{{- end }} +{{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume + emptyDir: {} +{{- end -}} +{{- range .Values.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + defaultMode: {{ .defaultMode }} +{{- end }} +{{- range .Values.extraVolumeMounts }} + - name: {{ .name }} + persistentVolumeClaim: + claimName: {{ .existingClaim }} +{{- end }} +{{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + emptyDir: {} +{{- end -}} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/clusterrole.yaml b/infra/charts/feast/charts/grafana/templates/clusterrole.yaml new file mode 100644 index 00000000000..b3ef6ab3bf2 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/clusterrole.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.rbac.create (not .Values.rbac.namespaced) }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "grafana.fullname" . }}-clusterrole +{{- if or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.rbac.extraClusterRoleRules) }} +rules: +{{- if or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled }} +- apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] +{{- end}} +{{- with .Values.rbac.extraClusterRoleRules }} +{{ toYaml . | indent 0 }} +{{- end}} +{{- else }} +rules: [] +{{- end}} +{{- end}} diff --git a/infra/charts/feast/charts/grafana/templates/clusterrolebinding.yaml b/infra/charts/feast/charts/grafana/templates/clusterrolebinding.yaml new file mode 100644 index 00000000000..8ee08b2aa97 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create (not .Values.rbac.namespaced) }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "grafana.fullname" . }}-clusterrolebinding + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +subjects: + - kind: ServiceAccount + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ template "grafana.fullname" . }}-clusterrole + apiGroup: rbac.authorization.k8s.io +{{- end -}} diff --git a/infra/charts/feast/charts/grafana/templates/configmap-dashboard-provider.yaml b/infra/charts/feast/charts/grafana/templates/configmap-dashboard-provider.yaml new file mode 100644 index 00000000000..af5d464b688 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/configmap-dashboard-provider.yaml @@ -0,0 +1,25 @@ +{{- if .Values.sidecar.dashboards.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "grafana.fullname" . }}-config-dashboards + namespace: {{ template "grafana.namespace" . }} +data: + provider.yaml: |- + apiVersion: 1 + providers: + - name: '{{ .Values.sidecar.dashboards.provider.name }}' + orgId: {{ .Values.sidecar.dashboards.provider.orgid }} + folder: '{{ .Values.sidecar.dashboards.provider.folder }}' + type: {{ .Values.sidecar.dashboards.provider.type }} + disableDeletion: {{ .Values.sidecar.dashboards.provider.disableDelete }} + allowUiUpdates: {{ .Values.sidecar.dashboards.provider.allowUiUpdates }} + options: + path: {{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }} +{{- end}} diff --git a/infra/charts/feast/charts/grafana/templates/configmap.yaml b/infra/charts/feast/charts/grafana/templates/configmap.yaml new file mode 100644 index 00000000000..00c69572746 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/configmap.yaml @@ -0,0 +1,69 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +data: +{{- if .Values.plugins }} + plugins: {{ join "," .Values.plugins }} +{{- end }} + grafana.ini: | +{{- range $key, $value := index .Values "grafana.ini" }} + [{{ $key }}] + {{- range $elem, $elemVal := $value }} + {{ $elem }} = {{ $elemVal }} + {{- end }} +{{- end }} + +{{- if .Values.datasources }} +{{ $root := . }} + {{- range $key, $value := .Values.datasources }} + {{ $key }}: | +{{ tpl (toYaml $value | indent 4) $root }} + {{- end -}} +{{- end -}} + +{{- if .Values.notifiers }} + {{- range $key, $value := .Values.notifiers }} + {{ $key }}: | +{{ toYaml $value | indent 4 }} + {{- end -}} +{{- end -}} + +{{- if .Values.dashboardProviders }} + {{- range $key, $value := .Values.dashboardProviders }} + {{ $key }}: | +{{ toYaml $value | indent 4 }} + {{- end -}} +{{- 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 }} + + {{- 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 }} + -H "Accept: application/json" \ + -H "Content-Type: application/json;charset=UTF-8" \ + {{ 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 }}| sed 's|\"datasource\":[^,]*|\"datasource\": \"{{ $value.datasource }}\"|g'{{ end }}{{- if $value.b64content -}} | base64 -d {{- end -}} \ + > /var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json + {{- end -}} + {{- end }} + {{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/dashboards-json-configmap.yaml b/infra/charts/feast/charts/grafana/templates/dashboards-json-configmap.yaml new file mode 100644 index 00000000000..59e0be64157 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/dashboards-json-configmap.yaml @@ -0,0 +1,35 @@ +{{- if .Values.dashboards }} +{{ $files := .Files }} +{{- range $provider, $dashboards := .Values.dashboards }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" $ }}-dashboards-{{ $provider }} + namespace: {{ template "grafana.namespace" $ }} + labels: + {{- include "grafana.labels" $ | nindent 4 }} + dashboard-provider: {{ $provider }} +{{- if $dashboards }} +data: +{{- $dashboardFound := false }} +{{- range $key, $value := $dashboards }} +{{- if (or (hasKey $value "json") (hasKey $value "file")) }} +{{- $dashboardFound = true }} +{{ print $key | indent 2 }}.json: +{{- if hasKey $value "json" }} + |- +{{ $value.json | indent 6 }} +{{- end }} +{{- if hasKey $value "file" }} +{{ toYaml ( $files.Get $value.file ) | indent 4}} +{{- end }} +{{- end }} +{{- end }} +{{- if not $dashboardFound }} + {} +{{- end }} +{{- end }} +--- +{{- end }} + +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/deployment.yaml b/infra/charts/feast/charts/grafana/templates/deployment.yaml new file mode 100644 index 00000000000..27a4b76d474 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/deployment.yaml @@ -0,0 +1,44 @@ +{{ if (or (not .Values.persistence.enabled) (eq .Values.persistence.type "pvc")) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} +{{- with .Values.deploymentStrategy }} + strategy: +{{ toYaml . | trim | indent 4 }} +{{- end }} + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} +{{- with .Values.podLabels }} +{{ toYaml . | indent 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 (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- end }} +{{- with .Values.podAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/headless-service.yaml b/infra/charts/feast/charts/grafana/templates/headless-service.yaml new file mode 100644 index 00000000000..2fa816e0450 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/headless-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset")}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "grafana.fullname" . }}-headless + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + clusterIP: None + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} + type: ClusterIP +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/ingress.yaml b/infra/charts/feast/charts/grafana/templates/ingress.yaml new file mode 100644 index 00000000000..202efb36196 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/ingress.yaml @@ -0,0 +1,42 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "grafana.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +apiVersion: networking.k8s.io/v1beta1 +{{ else }} +apiVersion: extensions/v1beta1 +{{ end -}} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.ingress.labels }} +{{ toYaml .Values.ingress.labels | indent 4 }} +{{- end }} +{{- with .Values.ingress.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- if .Values.ingress.tls }} + tls: +{{ toYaml .Values.ingress.tls | indent 4 }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ . }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: {{ $ingressPath }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/poddisruptionbudget.yaml b/infra/charts/feast/charts/grafana/templates/poddisruptionbudget.yaml new file mode 100644 index 00000000000..d6f230a8f25 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/poddisruptionbudget.yaml @@ -0,0 +1,22 @@ +{{- if .Values.podDisruptionBudget }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "grafana.name" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +spec: +{{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} +{{- end }} +{{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} +{{- end }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/podsecuritypolicy.yaml b/infra/charts/feast/charts/grafana/templates/podsecuritypolicy.yaml new file mode 100644 index 00000000000..c5e6ba05ead --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/podsecuritypolicy.yaml @@ -0,0 +1,52 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.rbac.pspUseAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + # Default set from Docker, without DAC_OVERRIDE or CHOWN + - FOWNER + - FSETID + - KILL + - SETGID + - SETUID + - SETPCAP + - NET_BIND_SERVICE + - NET_RAW + - SYS_CHROOT + - MKNOD + - AUDIT_WRITE + - SETFCAP + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/pvc.yaml b/infra/charts/feast/charts/grafana/templates/pvc.yaml new file mode 100644 index 00000000000..4727d0aa14c --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/pvc.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "pvc")}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .Values.persistence.finalizers }} + finalizers: +{{ toYaml . | indent 4 }} + {{- end }} +spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.storageClassName }} + storageClassName: {{ .Values.persistence.storageClassName }} + {{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/grafana/templates/role.yaml b/infra/charts/feast/charts/grafana/templates/role.yaml new file mode 100644 index 00000000000..c95c1d04241 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/role.yaml @@ -0,0 +1,32 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +{{- if or .Values.rbac.pspEnabled (and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.rbac.extraRoleRules))) }} +rules: +{{- if .Values.rbac.pspEnabled }} +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "grafana.fullname" . }}] +{{- end }} +{{- if and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled) }} +- apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] +{{- end }} +{{- with .Values.rbac.extraRoleRules }} +{{ toYaml . | indent 0 }} +{{- end}} +{{- else }} +rules: [] +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/rolebinding.yaml b/infra/charts/feast/charts/grafana/templates/rolebinding.yaml new file mode 100644 index 00000000000..c42229bf925 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/rolebinding.yaml @@ -0,0 +1,27 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "grafana.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +{{- if .Values.rbac.namespaced }} +roleRef: + kind: Role + name: {{ template "grafana.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} +{{- end -}} diff --git a/infra/charts/feast/charts/grafana/templates/secret-env.yaml b/infra/charts/feast/charts/grafana/templates/secret-env.yaml new file mode 100644 index 00000000000..5c09313e665 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/secret-env.yaml @@ -0,0 +1,14 @@ +{{- if .Values.envRenderSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "grafana.fullname" . }}-env + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +type: Opaque +data: +{{- range $key, $val := .Values.envRenderSecret }} + {{ $key }}: {{ $val | b64enc | quote }} +{{- end -}} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/secret.yaml b/infra/charts/feast/charts/grafana/templates/secret.yaml new file mode 100644 index 00000000000..f7ee9956b3c --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/secret.yaml @@ -0,0 +1,20 @@ +{{- if and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +type: Opaque +data: + admin-user: {{ .Values.adminUser | b64enc | quote }} + {{- if .Values.adminPassword }} + admin-password: {{ .Values.adminPassword | b64enc | quote }} + {{- else }} + admin-password: {{ randAlphaNum 40 | b64enc | quote }} + {{- end }} + {{- if not .Values.ldap.existingSecret }} + ldap-toml: {{ .Values.ldap.config | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/service.yaml b/infra/charts/feast/charts/grafana/templates/service.yaml new file mode 100644 index 00000000000..e06c27df32a --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/service.yaml @@ -0,0 +1,46 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.service.labels }} +{{ toYaml .Values.service.labels | indent 4 }} +{{- end }} +{{- with .Values.service.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} + type: ClusterIP + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{end}} +{{- else if eq .Values.service.type "LoadBalancer" }} + type: {{ .Values.service.type }} + {{- if .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} + {{- end -}} +{{- else }} + type: {{ .Values.service.type }} +{{- end }} +{{- if .Values.service.externalIPs }} + externalIPs: +{{ toYaml .Values.service.externalIPs | indent 4 }} +{{- end }} + ports: + - name: {{ .Values.service.portName }} + port: {{ .Values.service.port }} + protocol: TCP + targetPort: {{ .Values.service.targetPort }} +{{ if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{.Values.service.nodePort}} +{{ end }} + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} diff --git a/infra/charts/feast/charts/grafana/templates/serviceaccount.yaml b/infra/charts/feast/charts/grafana/templates/serviceaccount.yaml new file mode 100644 index 00000000000..7576eeef064 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.serviceAccount.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/statefulset.yaml b/infra/charts/feast/charts/grafana/templates/statefulset.yaml new file mode 100644 index 00000000000..afc26b7c2f5 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/statefulset.yaml @@ -0,0 +1,44 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset")}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + serviceName: {{ template "grafana.fullname" . }}-headless + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} + 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 not .Values.admin.existingSecret }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- end }} +{{- with .Values.podAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} + volumeClaimTemplates: + - metadata: + name: storage + spec: + accessModes: {{ .Values.persistence.accessModes }} + storageClassName: {{ .Values.persistence.storageClassName }} + resources: + requests: + storage: {{ .Values.persistence.size }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-configmap.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-configmap.yaml new file mode 100644 index 00000000000..ff53aaf1b36 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/tests/test-configmap.yaml @@ -0,0 +1,17 @@ +{{- if .Values.testFramework.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +data: + run.sh: |- + @test "Test Health" { + url="http://{{ template "grafana.fullname" . }}/api/health" + + code=$(wget --server-response --spider --timeout 10 --tries 1 ${url} 2>&1 | awk '/^ HTTP/{print $2}') + [ "$code" == "200" ] + } +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-podsecuritypolicy.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-podsecuritypolicy.yaml new file mode 100644 index 00000000000..eb5cbbcd701 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/tests/test-podsecuritypolicy.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + 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 + - secret +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-role.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-role.yaml new file mode 100644 index 00000000000..6b10677ae76 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/tests/test-role.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "grafana.fullname" . }}-test] +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-rolebinding.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-rolebinding.yaml new file mode 100644 index 00000000000..58fa5e78b56 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/tests/test-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "grafana.fullname" . }}-test +subjects: +- kind: ServiceAccount + name: {{ template "grafana.serviceAccountNameTest" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-serviceaccount.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-serviceaccount.yaml new file mode 100644 index 00000000000..5c335073371 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/tests/test-serviceaccount.yaml @@ -0,0 +1,9 @@ +{{- if and .Values.testFramework.enabled .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + name: {{ template "grafana.serviceAccountNameTest" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test.yaml b/infra/charts/feast/charts/grafana/templates/tests/test.yaml new file mode 100644 index 00000000000..7b2475c62c9 --- /dev/null +++ b/infra/charts/feast/charts/grafana/templates/tests/test.yaml @@ -0,0 +1,47 @@ +{{- if .Values.testFramework.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "grafana.fullname" . }}-test + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + namespace: {{ template "grafana.namespace" . }} +spec: + serviceAccountName: {{ template "grafana.serviceAccountNameTest" . }} + {{- if .Values.testFramework.securityContext }} + securityContext: {{ toYaml .Values.testFramework.securityContext | nindent 4 }} + {{- end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end}} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 4 }} + {{- end }} + containers: + - name: {{ .Release.Name }}-test + image: "{{ .Values.testFramework.image}}:{{ .Values.testFramework.tag }}" + command: ["/opt/bats/bin/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + volumes: + - name: tests + configMap: + name: {{ template "grafana.fullname" . }}-test + restartPolicy: Never +{{- end }} diff --git a/infra/charts/feast/charts/grafana/values.yaml b/infra/charts/feast/charts/grafana/values.yaml new file mode 100644 index 00000000000..cb1467159df --- /dev/null +++ b/infra/charts/feast/charts/grafana/values.yaml @@ -0,0 +1,485 @@ +rbac: + create: true + pspEnabled: true + pspUseAppArmor: true + namespaced: false + extraRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] + extraClusterRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] +serviceAccount: + create: true + name: + nameTest: +# annotations: + +replicas: 1 + +## See `kubectl explain poddisruptionbudget.spec` for more +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} +# 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: grafana/grafana + tag: 6.6.2 + 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/ + ## + # pullSecrets: + # - myRegistrKeySecretName + +testFramework: + enabled: true + image: "bats/bats" + tag: "v1.1.0" + securityContext: {} + +securityContext: + runAsUser: 472 + fsGroup: 472 + + +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 + + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +downloadDashboardsImage: + repository: curlimages/curl + tag: 7.68.0 + pullPolicy: IfNotPresent + +downloadDashboards: + env: {} + +## Pod Annotations +# podAnnotations: {} + +## Pod Labels +# podLabels: {} + +podPortName: grafana + +## 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: + type: ClusterIP + port: 80 + targetPort: 3000 + # targetPort: 4181 To be used with a proxy extraContainer + annotations: {} + labels: {} + portName: service + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + labels: {} + path: / + 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 + 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 +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## +affinity: {} + +extraInitContainers: [] + +## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod +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 + +## 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 + # subPath: "" + # existingClaim: + +initChownData: + ## If false, data ownership will not be reset at startup + ## This allows the prometheus-server to be run with an arbitrary user + ## + enabled: true + + ## initChownData container image + ## + image: + repository: busybox + tag: "1.31.1" + 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 + + +# Administrator credentials when not using an existing secret (see below) +adminUser: admin +# adminPassword: strongpassword + +# Use an existing secret for the admin user. +admin: + 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" + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: + +## Extra environment variables that will be pass onto deployment pods +env: {} + +## "valueFrom" environment variable references that will be added to deployment pods +## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core +## Renders in container spec as: +## env: +## ... +## - name: +## valueFrom: +## +envValueFrom: {} + +## 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 +envFromSecret: "" + +## Sensible environment variables that will be rendered as new secret object +## This can be useful for auth tokens, etc +envRenderSecret: {} + +## 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 + +## Additional grafana server volume mounts +# Defines additional volume mounts. +extraVolumeMounts: [] + # - name: extra-volume + # mountPath: /mnt/volume + # readOnly: true + # existingClaim: volume-claim + +## Pass the plugins you want installed as a list. +## +plugins: [] + # - digrich-bubblechart-panel + # - grafana-clock-panel + +## 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 + +## 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 + # local-dashboard-base64: + # url: https://example.com/repository/test-b64.json + # b64content: true + +## Reference to external ConfigMap per provider. Use provider name as key and ConfiMap 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/data + 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 +## 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: kiwigrid/k8s-sidecar:0.1.99 + imagePullPolicy: IfNotPresent + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + # skipTlsVerify Set to true to skip tls verification for kube api calls + # skipTlsVerify: true + dashboards: + enabled: false + ## 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 + SCProvider: true + # label that the configmaps with dashboards are marked with + label: grafana_dashboard + # 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 + # If specified, the sidecar will search for dashboard 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 + # 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 + datasources: + enabled: false + ## 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 + # label that the configmaps with datasources are marked with + label: grafana_datasource + # 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 + +## Override the deployment namespace +## +namespaceOverride: "" diff --git a/infra/charts/feast/charts/feast-core/.helmignore b/infra/charts/feast/charts/kafka/.helmignore similarity index 97% rename from infra/charts/feast/charts/feast-core/.helmignore rename to infra/charts/feast/charts/kafka/.helmignore index 50af0317254..f0c13194444 100644 --- a/infra/charts/feast/charts/feast-core/.helmignore +++ b/infra/charts/feast/charts/kafka/.helmignore @@ -19,4 +19,3 @@ .project .idea/ *.tmproj -.vscode/ diff --git a/infra/charts/feast/charts/kafka/Chart.yaml b/infra/charts/feast/charts/kafka/Chart.yaml new file mode 100755 index 00000000000..da92b400275 --- /dev/null +++ b/infra/charts/feast/charts/kafka/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +description: Apache Kafka is publish-subscribe messaging rethought as a distributed + commit log. +name: kafka +version: 0.20.8 +appVersion: 5.0.1 +keywords: +- kafka +- zookeeper +- kafka statefulset +home: https://kafka.apache.org/ +sources: +- https://github.com/kubernetes/charts/tree/master/incubator/zookeeper +- https://github.com/Yolean/kubernetes-kafka +- https://github.com/confluentinc/cp-docker-images +- https://github.com/apache/kafka +maintainers: +- name: faraazkhan + email: faraaz@rationalizeit.us +- name: h0tbird + email: marc.villacorta@gmail.com +- name: benjigoldberg + email: ben@spothero.com +icon: https://kafka.apache.org/images/logo.png diff --git a/infra/charts/feast/charts/kafka/OWNERS b/infra/charts/feast/charts/kafka/OWNERS new file mode 100644 index 00000000000..0ed92ba2d1a --- /dev/null +++ b/infra/charts/feast/charts/kafka/OWNERS @@ -0,0 +1,4 @@ +approvers: +- benjigoldberg +reviewers: +- benjigoldberg diff --git a/infra/charts/feast/charts/kafka/README.md b/infra/charts/feast/charts/kafka/README.md new file mode 100644 index 00000000000..6936f77a364 --- /dev/null +++ b/infra/charts/feast/charts/kafka/README.md @@ -0,0 +1,114 @@ +kafka +===== +Apache Kafka is publish-subscribe messaging rethought as a distributed commit log. + +Current chart version is `0.20.8` + +Source code can be found [here](https://kafka.apache.org/) + +## Chart Requirements + +| Repository | Name | Version | +|------------|------|---------| +| https://kubernetes-charts-incubator.storage.googleapis.com/ | zookeeper | 2.1.0 | + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| additionalPorts | object | `{}` | | +| affinity | object | `{}` | | +| configJob.backoffLimit | int | `6` | | +| configurationOverrides."confluent.support.metrics.enable" | bool | `false` | | +| envOverrides | object | `{}` | | +| external.distinct | bool | `false` | | +| external.dns.useExternal | bool | `true` | | +| external.dns.useInternal | bool | `false` | | +| external.domain | string | `"cluster.local"` | | +| external.enabled | bool | `false` | | +| external.firstListenerPort | int | `31090` | | +| external.init.image | string | `"lwolf/kubectl_deployer"` | | +| external.init.imagePullPolicy | string | `"IfNotPresent"` | | +| external.init.imageTag | string | `"0.4"` | | +| external.loadBalancerIP | list | `[]` | | +| external.loadBalancerSourceRanges | list | `[]` | | +| external.servicePort | int | `19092` | | +| external.type | string | `"NodePort"` | | +| headless.port | int | `9092` | | +| image | string | `"confluentinc/cp-kafka"` | | +| imagePullPolicy | string | `"IfNotPresent"` | | +| imageTag | string | `"5.0.1"` | | +| jmx.configMap.enabled | bool | `true` | | +| jmx.configMap.overrideConfig | object | `{}` | | +| jmx.configMap.overrideName | string | `""` | | +| jmx.port | int | `5555` | | +| jmx.whitelistObjectNames[0] | string | `"kafka.controller:*"` | | +| jmx.whitelistObjectNames[1] | string | `"kafka.server:*"` | | +| jmx.whitelistObjectNames[2] | string | `"java.lang:*"` | | +| jmx.whitelistObjectNames[3] | string | `"kafka.network:*"` | | +| jmx.whitelistObjectNames[4] | string | `"kafka.log:*"` | | +| kafkaHeapOptions | string | `"-Xmx1G -Xms1G"` | | +| logSubPath | string | `"logs"` | | +| nodeSelector | object | `{}` | | +| persistence.enabled | bool | `true` | | +| persistence.mountPath | string | `"/opt/kafka/data"` | | +| persistence.size | string | `"1Gi"` | | +| podAnnotations | object | `{}` | | +| podDisruptionBudget | object | `{}` | | +| podLabels | object | `{}` | | +| podManagementPolicy | string | `"OrderedReady"` | | +| prometheus.jmx.enabled | bool | `false` | | +| prometheus.jmx.image | string | `"solsson/kafka-prometheus-jmx-exporter@sha256"` | | +| prometheus.jmx.imageTag | string | `"a23062396cd5af1acdf76512632c20ea6be76885dfc20cd9ff40fb23846557e8"` | | +| prometheus.jmx.interval | string | `"10s"` | | +| prometheus.jmx.port | int | `5556` | | +| prometheus.jmx.resources | object | `{}` | | +| prometheus.jmx.scrapeTimeout | string | `"10s"` | | +| prometheus.kafka.affinity | object | `{}` | | +| prometheus.kafka.enabled | bool | `false` | | +| prometheus.kafka.image | string | `"danielqsj/kafka-exporter"` | | +| prometheus.kafka.imageTag | string | `"v1.2.0"` | | +| prometheus.kafka.interval | string | `"10s"` | | +| prometheus.kafka.nodeSelector | object | `{}` | | +| prometheus.kafka.port | int | `9308` | | +| prometheus.kafka.resources | object | `{}` | | +| prometheus.kafka.scrapeTimeout | string | `"10s"` | | +| prometheus.kafka.tolerations | list | `[]` | | +| prometheus.operator.enabled | bool | `false` | | +| prometheus.operator.prometheusRule.enabled | bool | `false` | | +| prometheus.operator.prometheusRule.namespace | string | `"monitoring"` | | +| prometheus.operator.prometheusRule.releaseNamespace | bool | `false` | | +| prometheus.operator.prometheusRule.rules[0].alert | string | `"KafkaNoActiveControllers"` | | +| prometheus.operator.prometheusRule.rules[0].annotations.message | string | `"The number of active controllers in {{ \"{{\" }} $labels.namespace {{ \"}}\" }} is less than 1. This usually means that some of the Kafka nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one whilst monitoring the under-replicated partitions graph)."` | | +| prometheus.operator.prometheusRule.rules[0].expr | string | `"max(kafka_controller_kafkacontroller_activecontrollercount_value) by (namespace) \u003c 1"` | | +| prometheus.operator.prometheusRule.rules[0].for | string | `"5m"` | | +| prometheus.operator.prometheusRule.rules[0].labels.severity | string | `"critical"` | | +| prometheus.operator.prometheusRule.rules[1].alert | string | `"KafkaMultipleActiveControllers"` | | +| prometheus.operator.prometheusRule.rules[1].annotations.message | string | `"The number of active controllers in {{ \"{{\" }} $labels.namespace {{ \"}}\" }} is greater than 1. This usually means that some of the Kafka nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one whilst monitoring the under-replicated partitions graph)."` | | +| prometheus.operator.prometheusRule.rules[1].expr | string | `"max(kafka_controller_kafkacontroller_activecontrollercount_value) by (namespace) \u003e 1"` | | +| prometheus.operator.prometheusRule.rules[1].for | string | `"5m"` | | +| prometheus.operator.prometheusRule.rules[1].labels.severity | string | `"critical"` | | +| prometheus.operator.prometheusRule.selector.prometheus | string | `"kube-prometheus"` | | +| prometheus.operator.serviceMonitor.namespace | string | `"monitoring"` | | +| prometheus.operator.serviceMonitor.releaseNamespace | bool | `false` | | +| prometheus.operator.serviceMonitor.selector.prometheus | string | `"kube-prometheus"` | | +| readinessProbe.failureThreshold | int | `3` | | +| readinessProbe.initialDelaySeconds | int | `30` | | +| readinessProbe.periodSeconds | int | `10` | | +| readinessProbe.successThreshold | int | `1` | | +| readinessProbe.timeoutSeconds | int | `5` | | +| replicas | int | `3` | | +| resources | object | `{}` | | +| securityContext | object | `{}` | | +| terminationGracePeriodSeconds | int | `60` | | +| tolerations | list | `[]` | | +| topics | list | `[]` | | +| updateStrategy.type | string | `"OnDelete"` | | +| zookeeper.affinity | object | `{}` | | +| zookeeper.enabled | bool | `true` | | +| zookeeper.env.ZK_HEAP_SIZE | string | `"1G"` | | +| zookeeper.image.PullPolicy | string | `"IfNotPresent"` | | +| zookeeper.persistence.enabled | bool | `false` | | +| zookeeper.port | int | `2181` | | +| zookeeper.resources | string | `nil` | | +| zookeeper.url | string | `""` | | diff --git a/infra/charts/feast/charts/kafka/charts/zookeeper-2.1.0.tgz b/infra/charts/feast/charts/kafka/charts/zookeeper-2.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..76d35b5ea7eb1fd642475efb471d14439069a579 GIT binary patch literal 10646 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 literal 0 HcmV?d00001 diff --git a/infra/charts/feast/charts/kafka/requirements.lock b/infra/charts/feast/charts/kafka/requirements.lock new file mode 100644 index 00000000000..2df3aa8437e --- /dev/null +++ b/infra/charts/feast/charts/kafka/requirements.lock @@ -0,0 +1,6 @@ +dependencies: +- name: zookeeper + repository: https://kubernetes-charts-incubator.storage.googleapis.com/ + version: 2.1.0 +digest: sha256:f50b0b5f50f4938a5369c5ea479030a4f87e99aecb7752ab434f75a6c39f304a +generated: "2019-11-05T16:37:25.868424523-06:00" diff --git a/infra/charts/feast/charts/kafka/requirements.yaml b/infra/charts/feast/charts/kafka/requirements.yaml new file mode 100644 index 00000000000..4d2a03f4cba --- /dev/null +++ b/infra/charts/feast/charts/kafka/requirements.yaml @@ -0,0 +1,5 @@ +dependencies: +- name: zookeeper + version: 2.1.0 + repository: https://kubernetes-charts-incubator.storage.googleapis.com/ + condition: kafka.zookeeper.enabled,zookeeper.enabled diff --git a/infra/charts/feast/charts/kafka/templates/NOTES.txt b/infra/charts/feast/charts/kafka/templates/NOTES.txt new file mode 100644 index 00000000000..fb35027a115 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/NOTES.txt @@ -0,0 +1,76 @@ +### Connecting to Kafka from inside Kubernetes + +You can connect to Kafka by running a simple pod in the K8s cluster like this with a configuration like this: + + apiVersion: v1 + kind: Pod + metadata: + name: testclient + namespace: {{ .Release.Namespace }} + spec: + containers: + - name: kafka + image: {{ .Values.image }}:{{ .Values.imageTag }} + command: + - sh + - -c + - "exec tail -f /dev/null" + +Once you have the testclient pod above running, you can list all kafka +topics with: + + kubectl -n {{ .Release.Namespace }} exec testclient -- kafka-topics --zookeeper {{ .Release.Name }}-zookeeper:2181 --list + +To create a new topic: + + kubectl -n {{ .Release.Namespace }} exec testclient -- kafka-topics --zookeeper {{ .Release.Name }}-zookeeper:2181 --topic test1 --create --partitions 1 --replication-factor 1 + +To listen for messages on a topic: + + kubectl -n {{ .Release.Namespace }} exec -ti testclient -- kafka-console-consumer --bootstrap-server {{ include "kafka.fullname" . }}:9092 --topic test1 --from-beginning + +To stop the listener session above press: Ctrl+C + +To start an interactive message producer session: + kubectl -n {{ .Release.Namespace }} exec -ti testclient -- kafka-console-producer --broker-list {{ include "kafka.fullname" . }}-headless:9092 --topic test1 + +To create a message in the above session, simply type the message and press "enter" +To end the producer session try: Ctrl+C + +If you specify "zookeeper.connect" in configurationOverrides, please replace "{{ .Release.Name }}-zookeeper:2181" with the value of "zookeeper.connect", or you will get error. + +{{ if .Values.external.enabled }} +### Connecting to Kafka from outside Kubernetes + +You have enabled the external access feature of this chart. + +**WARNING:** By default this feature allows Kafka clients outside Kubernetes to +connect to Kafka via NodePort(s) in `PLAINTEXT`. + +Please see this chart's README.md for more details and guidance. + +If you wish to connect to Kafka from outside please configure your external Kafka +clients to point at the following brokers. Please allow a few minutes for all +associated resources to become healthy. + {{ $fullName := include "kafka.fullname" . }} + {{- $replicas := .Values.replicas | int }} + {{- $servicePort := .Values.external.servicePort | int}} + {{- $root := . }} + {{- range $i, $e := until $replicas }} + {{- $externalListenerPort := add $root.Values.external.firstListenerPort $i }} + {{- if $root.Values.external.distinct }} +{{ printf "%s-%d.%s:%d" $root.Release.Name $i $root.Values.external.domain $servicePort | indent 2 }} + {{- else }} +{{ printf "%s.%s:%d" $root.Release.Name $root.Values.external.domain $externalListenerPort | indent 2 }} + {{- end }} + {{- end }} +{{- end }} + +{{ if .Values.prometheus.jmx.enabled }} +To view JMX configuration (pull request/updates to improve defaults are encouraged): + {{ if .Values.jmx.configMap.overrideName }} + kubectl -n {{ .Release.Namespace }} describe configmap {{ .Values.jmx.configMap.overrideName }} + {{ else }} + kubectl -n {{ .Release.Namespace }} describe configmap {{ include "kafka.fullname" . }}-metrics + {{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/_helpers.tpl b/infra/charts/feast/charts/kafka/templates/_helpers.tpl new file mode 100644 index 00000000000..03bfc0ace43 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/_helpers.tpl @@ -0,0 +1,128 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kafka.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 "kafka.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified zookeeper name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "kafka.zookeeper.fullname" -}} +{{- if .Values.zookeeper.fullnameOverride -}} +{{- .Values.zookeeper.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "zookeeper" .Values.zookeeper.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Form the Zookeeper URL. If zookeeper is installed as part of this chart, use k8s service discovery, +else use user-provided URL +*/}} +{{- define "zookeeper.url" }} +{{- $port := .Values.zookeeper.port | toString }} +{{- if .Values.zookeeper.enabled -}} +{{- printf "%s:%s" (include "kafka.zookeeper.fullname" .) $port }} +{{- else -}} +{{- $zookeeperConnect := printf "%s:%s" .Values.zookeeper.url $port }} +{{- $zookeeperConnectOverride := index .Values "configurationOverrides" "zookeeper.connect" }} +{{- default $zookeeperConnect $zookeeperConnectOverride }} +{{- end -}} +{{- end -}} + +{{/* +Derive offsets.topic.replication.factor in following priority order: configurationOverrides, replicas +*/}} +{{- define "kafka.replication.factor" }} +{{- $replicationFactorOverride := index .Values "configurationOverrides" "offsets.topic.replication.factor" }} +{{- default .Values.replicas $replicationFactorOverride }} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kafka.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create unified labels for kafka components +*/}} + +{{- define "kafka.common.matchLabels" -}} +app.kubernetes.io/name: {{ include "kafka.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{- define "kafka.common.metaLabels" -}} +helm.sh/chart: {{ include "kafka.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{- define "kafka.broker.matchLabels" -}} +app.kubernetes.io/component: kafka-broker +{{ include "kafka.common.matchLabels" . }} +{{- end -}} + +{{- define "kafka.broker.labels" -}} +{{ include "kafka.common.metaLabels" . }} +{{ include "kafka.broker.matchLabels" . }} +{{- end -}} + +{{- define "kafka.config.matchLabels" -}} +app.kubernetes.io/component: kafka-config +{{ include "kafka.common.matchLabels" . }} +{{- end -}} + +{{- define "kafka.config.labels" -}} +{{ include "kafka.common.metaLabels" . }} +{{ include "kafka.config.matchLabels" . }} +{{- end -}} + +{{- define "kafka.monitor.matchLabels" -}} +app.kubernetes.io/component: kafka-monitor +{{ include "kafka.common.matchLabels" . }} +{{- end -}} + +{{- define "kafka.monitor.labels" -}} +{{ include "kafka.common.metaLabels" . }} +{{ include "kafka.monitor.matchLabels" . }} +{{- end -}} + +{{- define "serviceMonitor.namespace" -}} +{{- if .Values.prometheus.operator.serviceMonitor.releaseNamespace -}} +{{ .Release.Namespace }} +{{- else -}} +{{ .Values.prometheus.operator.serviceMonitor.namespace }} +{{- end -}} +{{- end -}} + +{{- define "prometheusRule.namespace" -}} +{{- if .Values.prometheus.operator.prometheusRule.releaseNamespace -}} +{{ .Release.Namespace }} +{{- else -}} +{{ .Values.prometheus.operator.prometheusRule.namespace }} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/kafka/templates/configmap-config.yaml b/infra/charts/feast/charts/kafka/templates/configmap-config.yaml new file mode 100644 index 00000000000..020c8b55590 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/configmap-config.yaml @@ -0,0 +1,58 @@ +{{- if .Values.topics -}} +{{- $zk := include "zookeeper.url" . -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "kafka.config.labels" . | nindent 4 }} + name: {{ template "kafka.fullname" . }}-config +data: + runtimeConfig.sh: | + #!/bin/bash + set -e + cd /usr/bin + until kafka-configs --zookeeper {{ $zk }} --entity-type topics --describe || (( count++ >= 6 )) + do + echo "Waiting for Zookeeper..." + sleep 20 + done + until nc -z {{ template "kafka.fullname" . }} 9092 || (( retries++ >= 6 )) + do + echo "Waiting for Kafka..." + sleep 20 + done + echo "Applying runtime configuration using {{ .Values.image }}:{{ .Values.imageTag }}" + {{- range $n, $topic := .Values.topics }} + {{- if and $topic.partitions $topic.replicationFactor $topic.reassignPartitions }} + cat << EOF > {{ $topic.name }}-increase-replication-factor.json + {"version":1, "partitions":[ + {{- $partitions := (int $topic.partitions) }} + {{- $replicas := (int $topic.replicationFactor) }} + {{- range $i := until $partitions }} + {"topic":"{{ $topic.name }}","partition":{{ $i }},"replicas":[{{- range $j := until $replicas }}{{ $j }}{{- if ne $j (sub $replicas 1) }},{{- end }}{{- end }}]}{{- if ne $i (sub $partitions 1) }},{{- end }} + {{- end }} + ]} + EOF + kafka-reassign-partitions --zookeeper {{ $zk }} --reassignment-json-file {{ $topic.name }}-increase-replication-factor.json --execute + kafka-reassign-partitions --zookeeper {{ $zk }} --reassignment-json-file {{ $topic.name }}-increase-replication-factor.json --verify + {{- else if and $topic.partitions $topic.replicationFactor }} + kafka-topics --zookeeper {{ $zk }} --create --if-not-exists --force --topic {{ $topic.name }} --partitions {{ $topic.partitions }} --replication-factor {{ $topic.replicationFactor }} + {{- else if $topic.partitions }} + kafka-topics --zookeeper {{ $zk }} --alter --force --topic {{ $topic.name }} --partitions {{ $topic.partitions }} || true + {{- end }} + {{- if $topic.defaultConfig }} + kafka-configs --zookeeper {{ $zk }} --entity-type topics --entity-name {{ $topic.name }} --alter --force --delete-config {{ nospace $topic.defaultConfig }} || true + {{- end }} + {{- if $topic.config }} + kafka-configs --zookeeper {{ $zk }} --entity-type topics --entity-name {{ $topic.name }} --alter --force --add-config {{ nospace $topic.config }} + {{- end }} + kafka-configs --zookeeper {{ $zk }} --entity-type topics --entity-name {{ $topic.name }} --describe + {{- if $topic.acls }} + {{- range $a, $acl := $topic.acls }} + {{ if and $acl.user $acl.operations }} + kafka-acls --authorizer-properties zookeeper.connect={{ $zk }} --force --add --allow-principal User:{{ $acl.user }}{{- range $operation := $acl.operations }} --operation {{ $operation }} {{- end }} --topic {{ $topic.name }} {{ $topic.extraParams }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/infra/charts/feast/charts/kafka/templates/configmap-jmx.yaml b/infra/charts/feast/charts/kafka/templates/configmap-jmx.yaml new file mode 100644 index 00000000000..9eae92106ab --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/configmap-jmx.yaml @@ -0,0 +1,64 @@ +{{- if and .Values.prometheus.jmx.enabled .Values.jmx.configMap.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "kafka.fullname" . }}-metrics + labels: + {{- include "kafka.monitor.labels" . | nindent 4 }} +data: + jmx-kafka-prometheus.yml: |+ +{{- if .Values.jmx.configMap.overrideConfig }} +{{ toYaml .Values.jmx.configMap.overrideConfig | indent 4 }} +{{- else }} + jmxUrl: service:jmx:rmi:///jndi/rmi://127.0.0.1:{{ .Values.jmx.port }}/jmxrmi + lowercaseOutputName: true + lowercaseOutputLabelNames: true + ssl: false + {{ if .Values.jmx.whitelistObjectNames }} + whitelistObjectNames: ["{{ join "\",\"" .Values.jmx.whitelistObjectNames }}"] + {{ end }} + rules: + - pattern: kafka.controller<>(Value) + name: kafka_controller_$1_$2_$4 + labels: + broker_id: "$3" + - pattern: kafka.controller<>(Value) + name: kafka_controller_$1_$2_$3 + - pattern: kafka.controller<>(Value) + name: kafka_controller_$1_$2_$3 + - pattern: kafka.controller<>(Count) + name: kafka_controller_$1_$2_$3 + - pattern: kafka.server<>(Value) + name: kafka_server_$1_$2_$4 + labels: + client_id: "$3" + - pattern : kafka.network<>(Value) + name: kafka_network_$1_$2_$4 + labels: + network_processor: $3 + - pattern : kafka.network<>(Count) + name: kafka_network_$1_$2_$4 + labels: + request: $3 + - pattern: kafka.server<>(Count|OneMinuteRate) + name: kafka_server_$1_$2_$4 + labels: + topic: $3 + - pattern: kafka.server<>(Value) + name: kafka_server_$1_$2_$3_$4 + - pattern: kafka.server<>(Count|Value|OneMinuteRate) + name: kafka_server_$1_total_$2_$3 + - pattern: kafka.server<>(queue-size) + name: kafka_server_$1_$2 + - pattern: java.lang<(.+)>(\w+) + name: java_lang_$1_$4_$3_$2 + - pattern: java.lang<>(\w+) + name: java_lang_$1_$3_$2 + - pattern : java.lang + - pattern: kafka.log<>Value + name: kafka_log_$1_$2 + labels: + topic: $3 + partition: $4 +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/deployment-kafka-exporter.yaml b/infra/charts/feast/charts/kafka/templates/deployment-kafka-exporter.yaml new file mode 100644 index 00000000000..85e5a605b72 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/deployment-kafka-exporter.yaml @@ -0,0 +1,45 @@ +{{- if .Values.prometheus.kafka.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "kafka.fullname" . }}-exporter + labels: + {{- include "kafka.monitor.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "kafka.monitor.matchLabels" . | nindent 6 }} + template: + metadata: + annotations: +{{- if and .Values.prometheus.kafka.enabled (not .Values.prometheus.operator.enabled) }} + prometheus.io/scrape: "true" + prometheus.io/port: {{ .Values.prometheus.kafka.port | quote }} +{{- end }} + labels: + {{- include "kafka.monitor.labels" . | nindent 8 }} + spec: + containers: + - image: "{{ .Values.prometheus.kafka.image }}:{{ .Values.prometheus.kafka.imageTag }}" + name: kafka-exporter + args: + - --kafka.server={{ template "kafka.fullname" . }}:9092 + - --web.listen-address=:{{ .Values.prometheus.kafka.port }} + ports: + - containerPort: {{ .Values.prometheus.kafka.port }} + resources: +{{ toYaml .Values.prometheus.kafka.resources | indent 10 }} +{{- if .Values.prometheus.kafka.tolerations }} + tolerations: +{{ toYaml .Values.prometheus.kafka.tolerations | indent 8 }} +{{- end }} +{{- if .Values.prometheus.kafka.affinity }} + affinity: +{{ toYaml .Values.prometheus.kafka.affinity | indent 8 }} +{{- end }} +{{- if .Values.prometheus.kafka.nodeSelector }} + nodeSelector: +{{ toYaml .Values.prometheus.kafka.nodeSelector | indent 8 }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/job-config.yaml b/infra/charts/feast/charts/kafka/templates/job-config.yaml new file mode 100644 index 00000000000..13576b3fef0 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/job-config.yaml @@ -0,0 +1,29 @@ +{{- if .Values.topics -}} +{{- $scriptHash := include (print $.Template.BasePath "/configmap-config.yaml") . | sha256sum | trunc 8 -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ template "kafka.fullname" . }}-config-{{ $scriptHash }}" + labels: + {{- include "kafka.config.labels" . | nindent 4 }} +spec: + backoffLimit: {{ .Values.configJob.backoffLimit }} + template: + metadata: + labels: + {{- include "kafka.config.matchLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + volumes: + - name: config-volume + configMap: + name: {{ template "kafka.fullname" . }}-config + defaultMode: 0744 + containers: + - name: {{ template "kafka.fullname" . }}-config + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + command: ["/usr/local/script/runtimeConfig.sh"] + volumeMounts: + - name: config-volume + mountPath: "/usr/local/script" +{{- end -}} diff --git a/infra/charts/feast/charts/kafka/templates/podisruptionbudget.yaml b/infra/charts/feast/charts/kafka/templates/podisruptionbudget.yaml new file mode 100644 index 00000000000..7e1c03f9fae --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/podisruptionbudget.yaml @@ -0,0 +1,14 @@ +{{- if .Values.podDisruptionBudget }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ include "kafka.fullname" . }} + labels: + {{- include "kafka.broker.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "kafka.broker.matchLabels" . | nindent 6 }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} + +{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/prometheusrules.yaml b/infra/charts/feast/charts/kafka/templates/prometheusrules.yaml new file mode 100644 index 00000000000..4f74ad5d050 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/prometheusrules.yaml @@ -0,0 +1,16 @@ +{{ if and .Values.prometheus.operator.enabled .Values.prometheus.operator.prometheusRule.enabled .Values.prometheus.operator.prometheusRule.rules }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "kafka.fullname" . }} + namespace: {{ include "serviceMonitor.namespace" . }} + labels: + {{- include "kafka.monitor.labels" . | nindent 4 }} + {{- toYaml .Values.prometheus.operator.prometheusRule.selector | nindent 4 }} +spec: + groups: + - name: {{ include "kafka.fullname" . }} + rules: + {{- toYaml .Values.prometheus.operator.prometheusRule.rules | nindent 6 }} +{{- end }} + diff --git a/infra/charts/feast/charts/kafka/templates/service-brokers-external.yaml b/infra/charts/feast/charts/kafka/templates/service-brokers-external.yaml new file mode 100644 index 00000000000..3d35a8e3ff1 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/service-brokers-external.yaml @@ -0,0 +1,74 @@ +{{- if .Values.external.enabled }} + {{- $fullName := include "kafka.fullname" . }} + {{- $replicas := .Values.replicas | int }} + {{- $servicePort := .Values.external.servicePort }} + {{- $firstListenerPort := .Values.external.firstListenerPort }} + {{- $dnsPrefix := printf "%s" .Release.Name }} + {{- $root := . }} + {{- range $i, $e := until $replicas }} + {{- $externalListenerPort := add $root.Values.external.firstListenerPort $i }} + {{- $responsiblePod := printf "%s-%d" (printf "%s" $fullName) $i }} + {{- $distinctPrefix := printf "%s-%d" $dnsPrefix $i }} + {{- $loadBalancerIPLen := len $root.Values.external.loadBalancerIP }} + +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + {{- if $root.Values.external.distinct }} + {{- if $root.Values.external.dns.useInternal }} + dns.alpha.kubernetes.io/internal: "{{ $distinctPrefix }}.{{ $root.Values.external.domain }}" + {{- end }} + {{- if $root.Values.external.dns.useExternal }} + external-dns.alpha.kubernetes.io/hostname: "{{ $distinctPrefix }}.{{ $root.Values.external.domain }}" + {{- end }} + {{- else }} + {{- if $root.Values.external.dns.useInternal }} + dns.alpha.kubernetes.io/internal: "{{ $dnsPrefix }}.{{ $root.Values.external.domain }}" + {{- end }} + {{- if $root.Values.external.dns.useExternal }} + external-dns.alpha.kubernetes.io/hostname: "{{ $dnsPrefix }}.{{ $root.Values.external.domain }}" + {{- end }} + {{- end }} + {{- if $root.Values.external.annotations }} +{{ toYaml $root.Values.external.annotations | indent 4 }} + {{- end }} + name: {{ $root.Release.Name }}-{{ $i }}-external + labels: + {{- include "kafka.broker.labels" $root | nindent 4 }} + pod: {{ $responsiblePod | quote }} +spec: + type: {{ $root.Values.external.type }} + ports: + - name: external-broker + {{- if and (eq $root.Values.external.type "LoadBalancer") (not $root.Values.external.distinct) }} + port: {{ $firstListenerPort }} + {{- else }} + port: {{ $servicePort }} + {{- end }} + {{- if and (eq $root.Values.external.type "LoadBalancer") ($root.Values.external.distinct) }} + targetPort: {{ $servicePort }} + {{- else if and (eq $root.Values.external.type "LoadBalancer") (not $root.Values.external.distinct) }} + targetPort: {{ $firstListenerPort }} + {{- else }} + targetPort: {{ $externalListenerPort }} + {{- end }} + {{- if eq $root.Values.external.type "NodePort" }} + nodePort: {{ $externalListenerPort }} + {{- end }} + protocol: TCP + {{- if and (eq $root.Values.external.type "LoadBalancer") (eq $loadBalancerIPLen $replicas) }} + loadBalancerIP: {{ index $root.Values.external.loadBalancerIP $i }} + {{- end }} + {{- if $root.Values.external.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $root.Values.external.loadBalancerSourceRanges }} + - {{ . | quote}} + {{- end }} + {{- end }} + selector: + {{- include "kafka.broker.matchLabels" $root | nindent 4 }} + statefulset.kubernetes.io/pod-name: {{ $responsiblePod | quote }} + {{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/service-brokers.yaml b/infra/charts/feast/charts/kafka/templates/service-brokers.yaml new file mode 100644 index 00000000000..744843e1b71 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/service-brokers.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kafka.fullname" . }} + labels: + {{- include "kafka.broker.labels" . | nindent 4 }} +spec: + ports: + - name: broker + port: 9092 + targetPort: kafka +{{- if and .Values.prometheus.jmx.enabled .Values.prometheus.operator.enabled }} + - name: jmx-exporter + protocol: TCP + port: {{ .Values.jmx.port }} + targetPort: prometheus +{{- end }} + selector: + {{- include "kafka.broker.matchLabels" . | nindent 4 }} +--- +{{- if and .Values.prometheus.kafka.enabled .Values.prometheus.operator.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kafka.fullname" . }}-exporter + labels: + {{- include "kafka.monitor.labels" . | nindent 4 }} +spec: + ports: + - name: kafka-exporter + protocol: TCP + port: {{ .Values.prometheus.kafka.port }} + targetPort: {{ .Values.prometheus.kafka.port }} + selector: + {{- include "kafka.monitor.matchLabels" . | nindent 4 }} +{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/service-headless.yaml b/infra/charts/feast/charts/kafka/templates/service-headless.yaml new file mode 100644 index 00000000000..2fa7cf7763a --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/service-headless.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kafka.fullname" . }}-headless + labels: + {{- include "kafka.broker.labels" . | nindent 4 }} + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" +{{- if .Values.headless.annotations }} +{{ .Values.headless.annotations | toYaml | trimSuffix "\n" | indent 4 }} +{{- end }} +spec: + ports: + - name: broker + port: {{ .Values.headless.port }} +{{- if .Values.headless.targetPort }} + targetPort: {{ .Values.headless.targetPort }} +{{- end }} + clusterIP: None + selector: + {{- include "kafka.broker.matchLabels" . | nindent 4 }} diff --git a/infra/charts/feast/charts/kafka/templates/servicemonitors.yaml b/infra/charts/feast/charts/kafka/templates/servicemonitors.yaml new file mode 100644 index 00000000000..6d35feb71c5 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/servicemonitors.yaml @@ -0,0 +1,47 @@ +{{ if and .Values.prometheus.jmx.enabled .Values.prometheus.operator.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "kafka.fullname" . }} + namespace: {{ include "serviceMonitor.namespace" . }} + labels: + {{- include "kafka.monitor.labels" . | nindent 4 }} + {{- toYaml .Values.prometheus.operator.serviceMonitor.selector | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "kafka.broker.matchLabels" . | nindent 6 }} + endpoints: + - port: jmx-exporter + interval: {{ .Values.prometheus.jmx.interval }} + {{- if .Values.prometheus.jmx.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.jmx.scrapeTimeout }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{ end }} +--- +{{ if and .Values.prometheus.kafka.enabled .Values.prometheus.operator.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "kafka.fullname" . }}-exporter + namespace: {{ include "serviceMonitor.namespace" . }} + labels: + {{- include "kafka.monitor.labels" . | nindent 4 }} + {{ toYaml .Values.prometheus.operator.serviceMonitor.selector | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "kafka.monitor.matchLabels" . | nindent 6 }} + endpoints: + - port: kafka-exporter + interval: {{ .Values.prometheus.kafka.interval }} + {{- if .Values.prometheus.kafka.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.kafka.scrapeTimeout }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{ end }} diff --git a/infra/charts/feast/charts/kafka/templates/statefulset.yaml b/infra/charts/feast/charts/kafka/templates/statefulset.yaml new file mode 100644 index 00000000000..5e056ece1c2 --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/statefulset.yaml @@ -0,0 +1,272 @@ +{{- $advertisedListenersOverride := first (pluck "advertised.listeners" .Values.configurationOverrides) }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "kafka.fullname" . }} + labels: + {{- include "kafka.broker.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "kafka.broker.matchLabels" . | nindent 6 }} + serviceName: {{ include "kafka.fullname" . }}-headless + podManagementPolicy: {{ .Values.podManagementPolicy }} + updateStrategy: +{{ toYaml .Values.updateStrategy | indent 4 }} + replicas: {{ default 3 .Values.replicas }} + template: + metadata: +{{- if or .Values.podAnnotations (and .Values.prometheus.jmx.enabled (not .Values.prometheus.operator.enabled)) }} + annotations: +{{- if and .Values.prometheus.jmx.enabled (not .Values.prometheus.operator.enabled) }} + prometheus.io/scrape: "true" + prometheus.io/port: {{ .Values.prometheus.jmx.port | quote }} +{{- end }} +{{- if .Values.podAnnotations }} +{{ toYaml .Values.podAnnotations | indent 8 }} +{{- end }} +{{- end }} + labels: + {{- include "kafka.broker.labels" . | nindent 8 }} + {{- if .Values.podLabels }} + ## Custom pod labels +{{ toYaml .Values.podLabels | indent 8 }} + {{- end }} + spec: +{{- if .Values.schedulerName }} + schedulerName: "{{ .Values.schedulerName }}" +{{- end }} +{{- if .Values.serviceAccountName }} + serviceAccountName: {{ .Values.serviceAccountName }} +{{- end }} +{{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" +{{- end }} +{{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} +{{- end }} +{{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} +{{- end }} +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} +{{- end }} + containers: + {{- if .Values.prometheus.jmx.enabled }} + - name: metrics + image: "{{ .Values.prometheus.jmx.image }}:{{ .Values.prometheus.jmx.imageTag }}" + command: + - sh + - -exc + - | + trap "exit 0" TERM; \ + while :; do \ + java \ + -XX:+UnlockExperimentalVMOptions \ + -XX:+UseCGroupMemoryLimitForHeap \ + -XX:MaxRAMFraction=1 \ + -XshowSettings:vm \ + -jar \ + jmx_prometheus_httpserver.jar \ + {{ .Values.prometheus.jmx.port | quote }} \ + /etc/jmx-kafka/jmx-kafka-prometheus.yml & \ + wait $! || sleep 3; \ + done + ports: + - containerPort: {{ .Values.prometheus.jmx.port }} + name: prometheus + resources: +{{ toYaml .Values.prometheus.jmx.resources | indent 10 }} + volumeMounts: + - name: jmx-config + mountPath: /etc/jmx-kafka + {{- end }} + - name: {{ include "kafka.name" . }}-broker + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + livenessProbe: + exec: + command: + - sh + - -ec + - /usr/bin/jps | /bin/grep -q SupportedKafka + {{- if not .Values.livenessProbe }} + initialDelaySeconds: 30 + timeoutSeconds: 5 + {{- else }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds | default 30}} + {{- if .Values.livenessProbe.periodSeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + {{- end }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds | default 5}} + {{- if .Values.livenessProbe.successThreshold }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + {{- end }} + {{- if .Values.livenessProbe.failureThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- end }} + {{- end }} + readinessProbe: + tcpSocket: + port: kafka + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + ports: + - containerPort: 9092 + name: kafka + {{- if .Values.external.enabled }} + {{- $replicas := .Values.replicas | int }} + {{- $root := . }} + {{- range $i, $e := until $replicas }} + - containerPort: {{ add $root.Values.external.firstListenerPort $i }} + name: external-{{ $i }} + {{- end }} + {{- end }} + {{- if .Values.prometheus.jmx.enabled }} + - containerPort: {{ .Values.jmx.port }} + name: jmx + {{- end }} + {{- if .Values.additionalPorts }} +{{ toYaml .Values.additionalPorts | indent 8 }} + {{- end }} + resources: +{{ toYaml .Values.resources | indent 10 }} + env: + {{- if .Values.prometheus.jmx.enabled }} + - name: JMX_PORT + value: "{{ .Values.jmx.port }}" + {{- end }} + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KAFKA_HEAP_OPTS + value: {{ .Values.kafkaHeapOptions }} + - name: KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR + value: {{ include "kafka.replication.factor" . | quote }} + {{- if not (hasKey .Values.configurationOverrides "zookeeper.connect") }} + - name: KAFKA_ZOOKEEPER_CONNECT + value: {{ include "zookeeper.url" . | quote }} + {{- end }} + {{- if not (hasKey .Values.configurationOverrides "log.dirs") }} + - name: KAFKA_LOG_DIRS + value: {{ printf "%s/%s" .Values.persistence.mountPath .Values.logSubPath | quote }} + {{- end }} + {{- range $key, $value := .Values.configurationOverrides }} + - name: {{ printf "KAFKA_%s" $key | replace "." "_" | upper | quote }} + value: {{ $value | quote }} + {{- end }} + {{- if .Values.jmx.port }} + - name: KAFKA_JMX_PORT + value: "{{ .Values.jmx.port }}" + {{- end }} + {{- range $secret := .Values.secrets }} + {{- if not $secret.mountPath }} + {{- range $key := $secret.keys }} + - name: {{ (print ($secret.name | replace "-" "_") "_" $key) | upper }} + valueFrom: + secretKeyRef: + name: {{ $secret.name }} + key: {{ $key }} + {{- end }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.envOverrides }} + - name: {{ printf "%s" $key | replace "." "_" | upper | quote }} + value: {{ $value | quote }} + {{- end }} + # This is required because the Downward API does not yet support identification of + # pod numbering in statefulsets. Thus, we are required to specify a command which + # allows us to extract the pod ID for usage as the Kafka Broker ID. + # See: https://github.com/kubernetes/kubernetes/issues/31218 + command: + - sh + - -exc + - | + unset KAFKA_PORT && \ + export KAFKA_BROKER_ID=${POD_NAME##*-} && \ + {{- if eq .Values.external.type "LoadBalancer" }} + export LOAD_BALANCER_IP=$(echo '{{ .Values.external.loadBalancerIP }}' | tr -d '[]' | cut -d ' ' -f "$(($KAFKA_BROKER_ID + 1))") && \ + {{- end }} + {{- if eq .Values.external.type "NodePort" }} + export KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${POD_IP}:9092{{ if kindIs "string" $advertisedListenersOverride }}{{ printf ",%s" $advertisedListenersOverride }}{{ end }} && \ + {{- else }} + export KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${POD_NAME}.{{ include "kafka.fullname" . }}-headless.${POD_NAMESPACE}.svc.cluster.local:9092{{ if kindIs "string" $advertisedListenersOverride }}{{ printf ",%s" $advertisedListenersOverride }}{{ end }} && \ + {{- end }} + exec /etc/confluent/docker/run + volumeMounts: + - name: datadir + mountPath: {{ .Values.persistence.mountPath | quote }} + {{- range $secret := .Values.secrets }} + {{- if $secret.mountPath }} + {{- if $secret.keys }} + {{- range $key := $secret.keys }} + - name: {{ include "kafka.fullname" $ }}-{{ $secret.name }} + mountPath: {{ $secret.mountPath }}/{{ $key }} + subPath: {{ $key }} + readOnly: true + {{- end }} + {{- else }} + - name: {{ include "kafka.fullname" $ }}-{{ $secret.name }} + mountPath: {{ $secret.mountPath }} + readOnly: true + {{- end }} + {{- end }} + {{- end }} + volumes: + {{- if not .Values.persistence.enabled }} + - name: datadir + emptyDir: {} + {{- end }} + {{- if .Values.prometheus.jmx.enabled }} + - name: jmx-config + configMap: + {{- if .Values.jmx.configMap.overrideName }} + name: {{ .Values.jmx.configMap.overrideName }} + {{- else }} + name: {{ include "kafka.fullname" . }}-metrics + {{- end }} + {{- end }} + {{- if .Values.securityContext }} + securityContext: +{{ toYaml .Values.securityContext | indent 8 }} + {{- end }} + {{- range .Values.secrets }} + {{- if .mountPath }} + - name: {{ include "kafka.fullname" $ }}-{{ .name }} + secret: + secretName: {{ .name }} + {{- end }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- if .Values.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: datadir + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.persistence.size }} + {{- if .Values.persistence.storageClass }} + {{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" + {{- end }} + {{- end }} + {{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/tests/test_topic_create_consume_produce.yaml b/infra/charts/feast/charts/kafka/templates/tests/test_topic_create_consume_produce.yaml new file mode 100644 index 00000000000..3e7f4480daf --- /dev/null +++ b/infra/charts/feast/charts/kafka/templates/tests/test_topic_create_consume_produce.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-test-topic-create-consume-produce" + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: {{ .Release.Name }}-test-consume + image: {{ .Values.image }}:{{ .Values.imageTag }} + command: + - sh + - -c + - | + set -ex + # Create the topic + kafka-topics --zookeeper {{ include "zookeeper.url" . }} --topic helm-test-topic-create-consume-produce --create --partitions 1 --replication-factor 1 --if-not-exists && \ + # Create a message + MESSAGE="`date -u`" && \ + # Produce a test message to the topic + echo "$MESSAGE" | kafka-console-producer --broker-list {{ include "kafka.fullname" . }}:9092 --topic helm-test-topic-create-consume-produce && \ + # Consume a test message from the topic + kafka-console-consumer --bootstrap-server {{ include "kafka.fullname" . }}-headless:9092 --topic helm-test-topic-create-consume-produce --from-beginning --timeout-ms 5000 | grep "$MESSAGE" + restartPolicy: Never diff --git a/infra/charts/feast/charts/kafka/values.yaml b/infra/charts/feast/charts/kafka/values.yaml new file mode 100644 index 00000000000..f1e9664a798 --- /dev/null +++ b/infra/charts/feast/charts/kafka/values.yaml @@ -0,0 +1,503 @@ +# ------------------------------------------------------------------------------ +# Kafka: +# ------------------------------------------------------------------------------ + +## The StatefulSet installs 3 pods by default +replicas: 3 + +## The kafka image repository +image: "confluentinc/cp-kafka" + +## The kafka image tag +imageTag: "5.0.1" # Confluent image for Kafka 2.0.0 + +## Specify a imagePullPolicy +## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images +imagePullPolicy: "IfNotPresent" + +## Configure resource requests and limits +## ref: http://kubernetes.io/docs/user-guide/compute-resources/ +resources: {} + # limits: + # cpu: 200m + # memory: 1536Mi + # requests: + # cpu: 100m + # memory: 1024Mi +kafkaHeapOptions: "-Xmx1G -Xms1G" + +## Optional Container Security context +securityContext: {} + +## The StatefulSet Update Strategy which Kafka will use when changes are applied. +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies +updateStrategy: + type: "OnDelete" + +## Start and stop pods in Parallel or OrderedReady (one-by-one.) Note - Can not change after first release. +## ref: https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#pod-management-policy +podManagementPolicy: OrderedReady + +## Useful if using any custom authorizer +## Pass in some secrets to use (if required) +# secrets: +# - name: myKafkaSecret +# keys: +# - username +# - password +# # mountPath: /opt/kafka/secret +# - name: myZkSecret +# keys: +# - user +# - pass +# mountPath: /opt/zookeeper/secret + + +## The subpath within the Kafka container's PV where logs will be stored. +## This is combined with `persistence.mountPath`, to create, by default: /opt/kafka/data/logs +logSubPath: "logs" + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: + +## Use an alternate serviceAccount +## Useful when using images in custom repositories +# serviceAccountName: + +## Set a pod priorityClassName +# priorityClassName: high-priority + +## Pod scheduling preferences (by default keep pods within a release on separate nodes). +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## By default we don't set affinity +affinity: {} +## Alternatively, this typical example defines: +## antiAffinity (to keep Kafka pods on separate pods) +## and affinity (to encourage Kafka pods to be collocated with Zookeeper pods) +# affinity: +# podAntiAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# - labelSelector: +# matchExpressions: +# - key: app +# operator: In +# values: +# - kafka +# topologyKey: "kubernetes.io/hostname" +# podAffinity: +# preferredDuringSchedulingIgnoredDuringExecution: +# - weight: 50 +# podAffinityTerm: +# labelSelector: +# matchExpressions: +# - key: app +# operator: In +# values: +# - zookeeper +# topologyKey: "kubernetes.io/hostname" + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector +nodeSelector: {} + +## Readiness probe config. +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ +## +readinessProbe: + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + +## Period to wait for broker graceful shutdown (sigterm) before pod is killed (sigkill) +## ref: https://kubernetes-v1-4.github.io/docs/user-guide/production-pods/#lifecycle-hooks-and-termination-notice +## ref: https://kafka.apache.org/10/documentation.html#brokerconfigs controlled.shutdown.* +terminationGracePeriodSeconds: 60 + +# Tolerations for nodes that have taints on them. +# Useful if you want to dedicate nodes to just run kafka +# https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] +# tolerations: +# - key: "key" +# operator: "Equal" +# value: "value" +# effect: "NoSchedule" + +## Headless service. +## +headless: + # annotations: + # targetPort: + port: 9092 + +## External access. +## +external: + enabled: false + # type can be either NodePort or LoadBalancer + type: NodePort + # annotations: + # service.beta.kubernetes.io/openstack-internal-load-balancer: "true" + dns: + useInternal: false + useExternal: true + # If using external service type LoadBalancer and external dns, set distinct to true below. + # This creates an A record for each statefulset pod/broker. You should then map the + # A record of the broker to the EXTERNAL IP given by the LoadBalancer in your DNS server. + distinct: false + servicePort: 19092 + firstListenerPort: 31090 + domain: cluster.local + loadBalancerIP: [] + loadBalancerSourceRanges: [] + init: + image: "lwolf/kubectl_deployer" + imageTag: "0.4" + imagePullPolicy: "IfNotPresent" + +# Annotation to be added to Kafka pods +podAnnotations: {} + +# Labels to be added to Kafka pods +podLabels: {} + # service: broker + # team: developers + +podDisruptionBudget: {} + # maxUnavailable: 1 # Limits how many Kafka pods may be unavailable due to voluntary disruptions. + +## Configuration Overrides. Specify any Kafka settings you would like set on the StatefulSet +## here in map format, as defined in the official docs. +## ref: https://kafka.apache.org/documentation/#brokerconfigs +## +configurationOverrides: + "confluent.support.metrics.enable": false # Disables confluent metric submission + # "auto.leader.rebalance.enable": true + # "auto.create.topics.enable": true + # "controlled.shutdown.enable": true + # "controlled.shutdown.max.retries": 100 + + ## Options required for external access via NodePort + ## ref: + ## - http://kafka.apache.org/documentation/#security_configbroker + ## - https://cwiki.apache.org/confluence/display/KAFKA/KIP-103%3A+Separation+of+Internal+and+External+traffic + ## + ## Setting "advertised.listeners" here appends to "PLAINTEXT://${POD_IP}:9092,", ensure you update the domain + ## If external service type is Nodeport: + # "advertised.listeners": |- + # EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) + ## If external service type is LoadBalancer and distinct is true: + # "advertised.listeners": |- + # EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).cluster.local:19092 + ## If external service type is LoadBalancer and distinct is false: + # "advertised.listeners": |- + # EXTERNAL://${LOAD_BALANCER_IP}:31090 + ## Uncomment to define the EXTERNAL Listener protocol + # "listener.security.protocol.map": |- + # PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT + +## set extra ENVs +# key: "value" +envOverrides: {} + + +## A collection of additional ports to expose on brokers (formatted as normal containerPort yaml) +# Useful when the image exposes metrics (like prometheus, etc.) through a javaagent instead of a sidecar +additionalPorts: {} + +## Persistence configuration. Specify if and how to persist data to a persistent volume. +## +persistence: + enabled: true + + ## The size of the PersistentVolume to allocate to each Kafka Pod in the StatefulSet. For + ## production servers this number should likely be much larger. + ## + size: "1Gi" + + ## The location within the Kafka container where the PV will mount its storage and Kafka will + ## store its logs. + ## + mountPath: "/opt/kafka/data" + + ## Kafka data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: + +jmx: + ## Rules to apply to the Prometheus JMX Exporter. Note while lots of stats have been cleaned and exposed, + ## there are still more stats to clean up and expose, others will never get exposed. They keep lots of duplicates + ## that can be derived easily. The configMap in this chart cleans up the metrics it exposes to be in a Prometheus + ## format, eg topic, broker are labels and not part of metric name. Improvements are gladly accepted and encouraged. + configMap: + + ## Allows disabling the default configmap, note a configMap is needed + enabled: true + + ## Allows setting values to generate confimap + ## To allow all metrics through (warning its crazy excessive) comment out below `overrideConfig` and set + ## `whitelistObjectNames: []` + overrideConfig: {} + # jmxUrl: service:jmx:rmi:///jndi/rmi://127.0.0.1:5555/jmxrmi + # lowercaseOutputName: true + # lowercaseOutputLabelNames: true + # ssl: false + # rules: + # - pattern: ".*" + + ## If you would like to supply your own ConfigMap for JMX metrics, supply the name of that + ## ConfigMap as an `overrideName` here. + overrideName: "" + + ## Port the jmx metrics are exposed in native jmx format, not in Prometheus format + port: 5555 + + ## JMX Whitelist Objects, can be set to control which JMX metrics are exposed. Only whitelisted + ## values will be exposed via JMX Exporter. They must also be exposed via Rules. To expose all metrics + ## (warning its crazy excessive and they aren't formatted in a prometheus style) (1) `whitelistObjectNames: []` + ## (2) commented out above `overrideConfig`. + whitelistObjectNames: # [] + - kafka.controller:* + - kafka.server:* + - java.lang:* + - kafka.network:* + - kafka.log:* + +## Prometheus Exporters / Metrics +## +prometheus: + ## Prometheus JMX Exporter: exposes the majority of Kafkas metrics + jmx: + enabled: false + + ## The image to use for the metrics collector + image: solsson/kafka-prometheus-jmx-exporter@sha256 + + ## The image tag to use for the metrics collector + imageTag: a23062396cd5af1acdf76512632c20ea6be76885dfc20cd9ff40fb23846557e8 + + ## Interval at which Prometheus scrapes metrics, note: only used by Prometheus Operator + interval: 10s + + ## Timeout at which Prometheus timeouts scrape run, note: only used by Prometheus Operator + scrapeTimeout: 10s + + ## Port jmx-exporter exposes Prometheus format metrics to scrape + port: 5556 + + resources: {} + # limits: + # cpu: 200m + # memory: 1Gi + # requests: + # cpu: 100m + # memory: 100Mi + + ## Prometheus Kafka Exporter: exposes complimentary metrics to JMX Exporter + kafka: + enabled: false + + ## The image to use for the metrics collector + image: danielqsj/kafka-exporter + + ## The image tag to use for the metrics collector + imageTag: v1.2.0 + + ## Interval at which Prometheus scrapes metrics, note: only used by Prometheus Operator + interval: 10s + + ## Timeout at which Prometheus timeouts scrape run, note: only used by Prometheus Operator + scrapeTimeout: 10s + + ## Port kafka-exporter exposes for Prometheus to scrape metrics + port: 9308 + + ## Resource limits + resources: {} +# limits: +# cpu: 200m +# memory: 1Gi +# requests: +# cpu: 100m +# memory: 100Mi + + # Tolerations for nodes that have taints on them. + # Useful if you want to dedicate nodes to just run kafka-exporter + # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] + # tolerations: + # - key: "key" + # operator: "Equal" + # value: "value" + # effect: "NoSchedule" + + ## Pod scheduling preferences (by default keep pods within a release on separate nodes). + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## By default we don't set affinity + affinity: {} + ## Alternatively, this typical example defines: + ## affinity (to encourage Kafka Exporter pods to be collocated with Kafka pods) + # affinity: + # podAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - weight: 50 + # podAffinityTerm: + # labelSelector: + # matchExpressions: + # - key: app + # operator: In + # values: + # - kafka + # topologyKey: "kubernetes.io/hostname" + + ## Node labels for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} + + operator: + ## Are you using Prometheus Operator? + enabled: false + + serviceMonitor: + # Namespace in which to install the ServiceMonitor resource. + namespace: monitoring + # Use release namespace instead + releaseNamespace: false + + ## Defaults to whats used if you follow CoreOS [Prometheus Install Instructions](https://github.com/coreos/prometheus-operator/tree/master/helm#tldr) + ## [Prometheus Selector Label](https://github.com/coreos/prometheus-operator/blob/master/helm/prometheus/templates/prometheus.yaml#L65) + ## [Kube Prometheus Selector Label](https://github.com/coreos/prometheus-operator/blob/master/helm/kube-prometheus/values.yaml#L298) + selector: + prometheus: kube-prometheus + + prometheusRule: + ## Add Prometheus Rules? + enabled: false + + ## Namespace in which to install the PrometheusRule resource. + namespace: monitoring + # Use release namespace instead + releaseNamespace: false + + ## Defaults to whats used if you follow CoreOS [Prometheus Install Instructions](https://github.com/coreos/prometheus-operator/tree/master/helm#tldr) + ## [Prometheus Selector Label](https://github.com/coreos/prometheus-operator/blob/master/helm/prometheus/templates/prometheus.yaml#L65) + ## [Kube Prometheus Selector Label](https://github.com/coreos/prometheus-operator/blob/master/helm/kube-prometheus/values.yaml#L298) + selector: + prometheus: kube-prometheus + + ## Some example rules. + ## e.g. max(kafka_controller_kafkacontroller_activecontrollercount_value{service="my-kafka-release"}) by (service) < 1 + rules: + - alert: KafkaNoActiveControllers + annotations: + message: The number of active controllers in {{ "{{" }} $labels.namespace {{ "}}" }} is less than 1. This usually means that some of the Kafka nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one whilst monitoring the under-replicated partitions graph). + expr: max(kafka_controller_kafkacontroller_activecontrollercount_value) by (namespace) < 1 + for: 5m + labels: + severity: critical + - alert: KafkaMultipleActiveControllers + annotations: + message: The number of active controllers in {{ "{{" }} $labels.namespace {{ "}}" }} is greater than 1. This usually means that some of the Kafka nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one whilst monitoring the under-replicated partitions graph). + expr: max(kafka_controller_kafkacontroller_activecontrollercount_value) by (namespace) > 1 + for: 5m + labels: + severity: critical + +## Kafka Config job configuration +## +configJob: + ## Specify the number of retries before considering kafka-config job as failed. + ## https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#pod-backoff-failure-policy + backoffLimit: 6 + +## Topic creation and configuration. +## The job will be run on a deployment only when the config has been changed. +## - If 'partitions' and 'replicationFactor' are specified we create the topic (with --if-not-exists.) +## - If 'partitions', 'replicationFactor' and 'reassignPartitions' are specified we reassign the partitions to +## increase the replication factor of an existing topic. +## - If 'partitions' is specified we 'alter' the number of partitions. This will +## silently and safely fail if the new setting isn’t strictly larger than the old (i.e. a NOOP.) Do be aware of the +## implications for keyed topics (ref: https://docs.confluent.io/current/kafka/post-deployment.html#admin-operations) +## - If 'defaultConfig' is specified it's deleted from the topic configuration. If it isn't present, +## it will silently and safely fail. +## - If 'config' is specified it's added to the topic configuration. +## +## Note: To increase the 'replicationFactor' of a topic, 'reassignPartitions' must be set to true (see above). +## +topics: [] + # - name: myExistingTopicConfig + # config: "cleanup.policy=compact,delete.retention.ms=604800000" + # - name: myExistingTopicReassignPartitions + # partitions: 8 + # replicationFactor: 5 + # reassignPartitions: true + # - name: myExistingTopicPartitions + # partitions: 8 + # - name: myNewTopicWithConfig + # partitions: 8 + # replicationFactor: 3 + # defaultConfig: "segment.bytes,segment.ms" + # config: "cleanup.policy=compact,delete.retention.ms=604800000" + # - name: myAclTopicPartitions + # partitions: 8 + # acls: + # - user: read + # operations: [ Read ] + # - user: read_and_write + # operations: + # - Read + # - Write + # - user: all + # operations: [ All ] + +# ------------------------------------------------------------------------------ +# Zookeeper: +# ------------------------------------------------------------------------------ + +zookeeper: + ## If true, install the Zookeeper chart alongside Kafka + ## ref: https://github.com/kubernetes/charts/tree/master/incubator/zookeeper + enabled: true + + ## Configure Zookeeper resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: ~ + + ## Environmental variables to set in Zookeeper + env: + ## The JVM heap size to allocate to Zookeeper + ZK_HEAP_SIZE: "1G" + + persistence: + enabled: false + ## The amount of PV storage allocated to each Zookeeper pod in the statefulset + # size: "2Gi" + + ## Specify a Zookeeper imagePullPolicy + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + image: + PullPolicy: "IfNotPresent" + + ## If the Zookeeper Chart is disabled a URL and port are required to connect + url: "" + port: 2181 + + ## Pod scheduling preferences (by default keep pods within a release on separate nodes). + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## By default we don't set affinity: + affinity: {} # Criteria by which pod label-values influence scheduling for zookeeper pods. + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - topologyKey: "kubernetes.io/hostname" + # labelSelector: + # matchLabels: + # release: zookeeper diff --git a/infra/charts/feast/charts/postgresql/.helmignore b/infra/charts/feast/charts/postgresql/.helmignore new file mode 100644 index 00000000000..a1c17ae4508 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/.helmignore @@ -0,0 +1,2 @@ +.git +OWNERS \ No newline at end of file diff --git a/infra/charts/feast/charts/postgresql/Chart.yaml b/infra/charts/feast/charts/postgresql/Chart.yaml new file mode 100644 index 00000000000..f7b07dc0599 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +name: postgresql +version: 8.6.1 +appVersion: 11.7.0 +description: Chart for PostgreSQL, an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance. +keywords: + - postgresql + - postgres + - database + - sql + - replication + - cluster +home: https://www.postgresql.org/ +icon: https://bitnami.com/assets/stacks/postgresql/img/postgresql-stack-110x117.png +sources: + - https://github.com/bitnami/bitnami-docker-postgresql +maintainers: + - name: Bitnami + email: containers@bitnami.com + - name: desaintmartin + email: cedric@desaintmartin.fr +engine: gotpl diff --git a/infra/charts/feast/charts/postgresql/OWNERS b/infra/charts/feast/charts/postgresql/OWNERS new file mode 100644 index 00000000000..5fbcd3961a1 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/OWNERS @@ -0,0 +1,18 @@ +approvers: +- prydonius +- tompizmor +- sameersbn +- carrodher +- javsalgar +- juan131 +- desaintmartin +- miguelaeh +reviewers: +- prydonius +- tompizmor +- sameersbn +- carrodher +- javsalgar +- juan131 +- desaintmartin +- miguelaeh diff --git a/infra/charts/feast/charts/postgresql/README.md b/infra/charts/feast/charts/postgresql/README.md new file mode 100644 index 00000000000..2469239df24 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/README.md @@ -0,0 +1,134 @@ +postgresql +========== +Chart for PostgreSQL, an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance. + +Current chart version is `8.6.1` + +Source code can be found [here](https://www.postgresql.org/) + + + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| extraEnv | list | `[]` | | +| global.postgresql | object | `{}` | | +| image.debug | bool | `false` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.registry | string | `"docker.io"` | | +| image.repository | string | `"bitnami/postgresql"` | | +| image.tag | string | `"11.7.0-debian-10-r9"` | | +| ldap.baseDN | string | `""` | | +| ldap.bindDN | string | `""` | | +| ldap.bind_password | string | `nil` | | +| ldap.enabled | bool | `false` | | +| ldap.port | string | `""` | | +| ldap.prefix | string | `""` | | +| ldap.scheme | string | `""` | | +| ldap.search_attr | string | `""` | | +| ldap.search_filter | string | `""` | | +| ldap.server | string | `""` | | +| ldap.suffix | string | `""` | | +| ldap.tls | bool | `false` | | +| ldap.url | string | `""` | | +| livenessProbe.enabled | bool | `true` | | +| livenessProbe.failureThreshold | int | `6` | | +| livenessProbe.initialDelaySeconds | int | `30` | | +| livenessProbe.periodSeconds | int | `10` | | +| livenessProbe.successThreshold | int | `1` | | +| livenessProbe.timeoutSeconds | int | `5` | | +| master.affinity | object | `{}` | | +| master.annotations | object | `{}` | | +| master.extraInitContainers | string | `"# - name: do-something\n# image: busybox\n# command: ['do', 'something']\n"` | | +| master.extraVolumeMounts | list | `[]` | | +| master.extraVolumes | list | `[]` | | +| master.labels | object | `{}` | | +| master.nodeSelector | object | `{}` | | +| master.podAnnotations | object | `{}` | | +| master.podLabels | object | `{}` | | +| master.priorityClassName | string | `""` | | +| master.sidecars | list | `[]` | | +| master.tolerations | list | `[]` | | +| metrics.enabled | bool | `false` | | +| metrics.image.pullPolicy | string | `"IfNotPresent"` | | +| metrics.image.registry | string | `"docker.io"` | | +| metrics.image.repository | string | `"bitnami/postgres-exporter"` | | +| metrics.image.tag | string | `"0.8.0-debian-10-r28"` | | +| metrics.livenessProbe.enabled | bool | `true` | | +| metrics.livenessProbe.failureThreshold | int | `6` | | +| metrics.livenessProbe.initialDelaySeconds | int | `5` | | +| metrics.livenessProbe.periodSeconds | int | `10` | | +| metrics.livenessProbe.successThreshold | int | `1` | | +| metrics.livenessProbe.timeoutSeconds | int | `5` | | +| metrics.prometheusRule.additionalLabels | object | `{}` | | +| metrics.prometheusRule.enabled | bool | `false` | | +| metrics.prometheusRule.namespace | string | `""` | | +| metrics.prometheusRule.rules | list | `[]` | | +| metrics.readinessProbe.enabled | bool | `true` | | +| metrics.readinessProbe.failureThreshold | int | `6` | | +| metrics.readinessProbe.initialDelaySeconds | int | `5` | | +| metrics.readinessProbe.periodSeconds | int | `10` | | +| metrics.readinessProbe.successThreshold | int | `1` | | +| metrics.readinessProbe.timeoutSeconds | int | `5` | | +| metrics.securityContext.enabled | bool | `false` | | +| metrics.securityContext.runAsUser | int | `1001` | | +| metrics.service.annotations."prometheus.io/port" | string | `"9187"` | | +| metrics.service.annotations."prometheus.io/scrape" | string | `"true"` | | +| metrics.service.loadBalancerIP | string | `nil` | | +| metrics.service.type | string | `"ClusterIP"` | | +| metrics.serviceMonitor.additionalLabels | object | `{}` | | +| metrics.serviceMonitor.enabled | bool | `false` | | +| networkPolicy.allowExternal | bool | `true` | | +| networkPolicy.enabled | bool | `false` | | +| persistence.accessModes[0] | string | `"ReadWriteOnce"` | | +| persistence.annotations | object | `{}` | | +| persistence.enabled | bool | `true` | | +| persistence.mountPath | string | `"/bitnami/postgresql"` | | +| persistence.size | string | `"8Gi"` | | +| persistence.subPath | string | `""` | | +| postgresqlDataDir | string | `"/bitnami/postgresql/data"` | | +| postgresqlUsername | string | `"postgres"` | | +| readinessProbe.enabled | bool | `true` | | +| readinessProbe.failureThreshold | int | `6` | | +| readinessProbe.initialDelaySeconds | int | `5` | | +| readinessProbe.periodSeconds | int | `10` | | +| readinessProbe.successThreshold | int | `1` | | +| readinessProbe.timeoutSeconds | int | `5` | | +| replication.applicationName | string | `"my_application"` | | +| replication.enabled | bool | `false` | | +| replication.numSynchronousReplicas | int | `0` | | +| replication.password | string | `"repl_password"` | | +| replication.slaveReplicas | int | `1` | | +| replication.synchronousCommit | string | `"off"` | | +| replication.user | string | `"repl_user"` | | +| resources.requests.cpu | string | `"250m"` | | +| resources.requests.memory | string | `"256Mi"` | | +| securityContext.enabled | bool | `true` | | +| securityContext.fsGroup | int | `1001` | | +| securityContext.runAsUser | int | `1001` | | +| service.annotations | object | `{}` | | +| service.port | int | `5432` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.enabled | bool | `false` | | +| shmVolume.chmod.enabled | bool | `true` | | +| shmVolume.enabled | bool | `true` | | +| slave.affinity | object | `{}` | | +| slave.annotations | object | `{}` | | +| slave.extraInitContainers | string | `"# - name: do-something\n# image: busybox\n# command: ['do', 'something']\n"` | | +| slave.extraVolumeMounts | list | `[]` | | +| slave.extraVolumes | list | `[]` | | +| slave.labels | object | `{}` | | +| slave.nodeSelector | object | `{}` | | +| slave.podAnnotations | object | `{}` | | +| slave.podLabels | object | `{}` | | +| slave.priorityClassName | string | `""` | | +| slave.sidecars | list | `[]` | | +| slave.tolerations | list | `[]` | | +| updateStrategy.type | string | `"RollingUpdate"` | | +| volumePermissions.enabled | bool | `false` | | +| volumePermissions.image.pullPolicy | string | `"Always"` | | +| volumePermissions.image.registry | string | `"docker.io"` | | +| volumePermissions.image.repository | string | `"bitnami/minideb"` | | +| volumePermissions.image.tag | string | `"buster"` | | +| volumePermissions.securityContext.runAsUser | int | `0` | | diff --git a/infra/charts/feast/charts/postgresql/ci/default-values.yaml b/infra/charts/feast/charts/postgresql/ci/default-values.yaml new file mode 100644 index 00000000000..fc2ba605ada --- /dev/null +++ b/infra/charts/feast/charts/postgresql/ci/default-values.yaml @@ -0,0 +1 @@ +# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/infra/charts/feast/charts/postgresql/ci/shmvolume-disabled-values.yaml b/infra/charts/feast/charts/postgresql/ci/shmvolume-disabled-values.yaml new file mode 100644 index 00000000000..347d3b40a8e --- /dev/null +++ b/infra/charts/feast/charts/postgresql/ci/shmvolume-disabled-values.yaml @@ -0,0 +1,2 @@ +shmVolume: + enabled: false diff --git a/infra/charts/feast/charts/postgresql/files/README.md b/infra/charts/feast/charts/postgresql/files/README.md new file mode 100644 index 00000000000..1813a2feaaf --- /dev/null +++ b/infra/charts/feast/charts/postgresql/files/README.md @@ -0,0 +1 @@ +Copy here your postgresql.conf and/or pg_hba.conf files to use it as a config map. diff --git a/infra/charts/feast/charts/postgresql/files/conf.d/README.md b/infra/charts/feast/charts/postgresql/files/conf.d/README.md new file mode 100644 index 00000000000..184c1875d57 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/files/conf.d/README.md @@ -0,0 +1,4 @@ +If you don't want to provide the whole configuration file and only specify certain parameters, you can copy here your extended `.conf` files. +These files will be injected as a config maps and add/overwrite the default configuration using the `include_dir` directive that allows settings to be loaded from files other than the default `postgresql.conf`. + +More info in the [bitnami-docker-postgresql README](https://github.com/bitnami/bitnami-docker-postgresql#configuration-file). diff --git a/infra/charts/feast/charts/postgresql/files/docker-entrypoint-initdb.d/README.md b/infra/charts/feast/charts/postgresql/files/docker-entrypoint-initdb.d/README.md new file mode 100644 index 00000000000..cba38091e0f --- /dev/null +++ b/infra/charts/feast/charts/postgresql/files/docker-entrypoint-initdb.d/README.md @@ -0,0 +1,3 @@ +You can copy here your custom `.sh`, `.sql` or `.sql.gz` file so they are executed during the first boot of the image. + +More info in the [bitnami-docker-postgresql](https://github.com/bitnami/bitnami-docker-postgresql#initializing-a-new-instance) repository. \ No newline at end of file diff --git a/infra/charts/feast/charts/postgresql/templates/NOTES.txt b/infra/charts/feast/charts/postgresql/templates/NOTES.txt new file mode 100644 index 00000000000..3b5e6c60dfd --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/NOTES.txt @@ -0,0 +1,60 @@ +** Please be patient while the chart is being deployed ** + +PostgreSQL can be accessed via port {{ template "postgresql.port" . }} on the following DNS name from within your cluster: + + {{ template "postgresql.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - Read/Write connection +{{- if .Values.replication.enabled }} + {{ template "postgresql.fullname" . }}-read.{{ .Release.Namespace }}.svc.cluster.local - Read only connection +{{- end }} + +{{- if and .Values.postgresqlPostgresPassword (not (eq .Values.postgresqlUsername "postgres")) }} + +To get the password for "postgres" run: + + export POSTGRES_ADMIN_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "postgresql.secretName" . }} -o jsonpath="{.data.postgresql-postgres-password}" | base64 --decode) +{{- end }} + +To get the password for "{{ template "postgresql.username" . }}" run: + + export POSTGRES_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "postgresql.secretName" . }} -o jsonpath="{.data.postgresql-password}" | base64 --decode) + +To connect to your database run the following command: + + kubectl run {{ template "postgresql.fullname" . }}-client --rm --tty -i --restart='Never' --namespace {{ .Release.Namespace }} --image {{ template "postgresql.image" . }} --env="PGPASSWORD=$POSTGRES_PASSWORD" {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} + --labels="{{ template "postgresql.fullname" . }}-client=true" {{- end }} --command -- psql --host {{ template "postgresql.fullname" . }} -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} -p {{ template "postgresql.port" . }} + +{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} +Note: Since NetworkPolicy is enabled, only pods with label {{ template "postgresql.fullname" . }}-client=true" will be able to connect to this PostgreSQL cluster. +{{- end }} + +To connect to your database from outside the cluster execute the following commands: + +{{- if contains "NodePort" .Values.service.type }} + + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "postgresql.fullname" . }}) + {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host $NODE_IP --port $NODE_PORT -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} + +{{- else if contains "LoadBalancer" .Values.service.type }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "postgresql.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "postgresql.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host $SERVICE_IP --port {{ template "postgresql.port" . }} -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} + +{{- else if contains "ClusterIP" .Values.service.type }} + + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "postgresql.fullname" . }} {{ template "postgresql.port" . }}:{{ template "postgresql.port" . }} & + {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host 127.0.0.1 -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} -p {{ template "postgresql.port" . }} + +{{- end }} + +{{- include "postgresql.validateValues" . -}} + +{{- if and (contains "bitnami/" .Values.image.repository) (not (.Values.image.tag | toString | regexFind "-r\\d+$|sha256:")) }} + +WARNING: Rolling tag detected ({{ .Values.image.repository }}:{{ .Values.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ + +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/_helpers.tpl b/infra/charts/feast/charts/postgresql/templates/_helpers.tpl new file mode 100644 index 00000000000..3ee55726e7d --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/_helpers.tpl @@ -0,0 +1,420 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "postgresql.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). +*/}} +{{- define "postgresql.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "postgresql.master.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- $fullname := default (printf "%s-%s" .Release.Name $name) .Values.fullnameOverride -}} +{{- if .Values.replication.enabled -}} +{{- printf "%s-%s" $fullname "master" | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s" $fullname | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "postgresql.networkPolicy.apiVersion" -}} +{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} +"extensions/v1beta1" +{{- else if semverCompare "^1.7-0" .Capabilities.KubeVersion.GitVersion -}} +"networking.k8s.io/v1" +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "postgresql.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the proper PostgreSQL image name +*/}} +{{- define "postgresql.image" -}} +{{- $registryName := .Values.image.registry -}} +{{- $repositoryName := .Values.image.repository -}} +{{- $tag := .Values.image.tag | toString -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. +Also, we can't use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} + {{- if .Values.global.imageRegistry }} + {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} + {{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} + {{- end -}} +{{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL postgres user password +*/}} +{{- define "postgresql.postgres.password" -}} +{{- if .Values.global.postgresql.postgresqlPostgresPassword }} + {{- .Values.global.postgresql.postgresqlPostgresPassword -}} +{{- else if .Values.postgresqlPostgresPassword -}} + {{- .Values.postgresqlPostgresPassword -}} +{{- else -}} + {{- randAlphaNum 10 -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL password +*/}} +{{- define "postgresql.password" -}} +{{- if .Values.global.postgresql.postgresqlPassword }} + {{- .Values.global.postgresql.postgresqlPassword -}} +{{- else if .Values.postgresqlPassword -}} + {{- .Values.postgresqlPassword -}} +{{- else -}} + {{- randAlphaNum 10 -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL replication password +*/}} +{{- define "postgresql.replication.password" -}} +{{- if .Values.global.postgresql.replicationPassword }} + {{- .Values.global.postgresql.replicationPassword -}} +{{- else if .Values.replication.password -}} + {{- .Values.replication.password -}} +{{- else -}} + {{- randAlphaNum 10 -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL username +*/}} +{{- define "postgresql.username" -}} +{{- if .Values.global.postgresql.postgresqlUsername }} + {{- .Values.global.postgresql.postgresqlUsername -}} +{{- else -}} + {{- .Values.postgresqlUsername -}} +{{- end -}} +{{- end -}} + + +{{/* +Return PostgreSQL replication username +*/}} +{{- define "postgresql.replication.username" -}} +{{- if .Values.global.postgresql.replicationUser }} + {{- .Values.global.postgresql.replicationUser -}} +{{- else -}} + {{- .Values.replication.user -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL port +*/}} +{{- define "postgresql.port" -}} +{{- if .Values.global.postgresql.servicePort }} + {{- .Values.global.postgresql.servicePort -}} +{{- else -}} + {{- .Values.service.port -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL created database +*/}} +{{- define "postgresql.database" -}} +{{- if .Values.global.postgresql.postgresqlDatabase }} + {{- .Values.global.postgresql.postgresqlDatabase -}} +{{- else if .Values.postgresqlDatabase -}} + {{- .Values.postgresqlDatabase -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper image name to change the volume permissions +*/}} +{{- define "postgresql.volumePermissions.image" -}} +{{- $registryName := .Values.volumePermissions.image.registry -}} +{{- $repositoryName := .Values.volumePermissions.image.repository -}} +{{- $tag := .Values.volumePermissions.image.tag | toString -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. +Also, we can't use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} + {{- if .Values.global.imageRegistry }} + {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} + {{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} + {{- end -}} +{{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper PostgreSQL metrics image name +*/}} +{{- define "postgresql.metrics.image" -}} +{{- $registryName := default "docker.io" .Values.metrics.image.registry -}} +{{- $repositoryName := .Values.metrics.image.repository -}} +{{- $tag := default "latest" .Values.metrics.image.tag | toString -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. +Also, we can't use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} + {{- if .Values.global.imageRegistry }} + {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} + {{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} + {{- end -}} +{{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Get the password secret. +*/}} +{{- define "postgresql.secretName" -}} +{{- if .Values.global.postgresql.existingSecret }} + {{- printf "%s" .Values.global.postgresql.existingSecret -}} +{{- else if .Values.existingSecret -}} + {{- printf "%s" .Values.existingSecret -}} +{{- else -}} + {{- printf "%s" (include "postgresql.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a secret object should be created +*/}} +{{- define "postgresql.createSecret" -}} +{{- if .Values.global.postgresql.existingSecret }} +{{- else if .Values.existingSecret -}} +{{- else -}} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Get the configuration ConfigMap name. +*/}} +{{- define "postgresql.configurationCM" -}} +{{- if .Values.configurationConfigMap -}} +{{- printf "%s" (tpl .Values.configurationConfigMap $) -}} +{{- else -}} +{{- printf "%s-configuration" (include "postgresql.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Get the extended configuration ConfigMap name. +*/}} +{{- define "postgresql.extendedConfigurationCM" -}} +{{- if .Values.extendedConfConfigMap -}} +{{- printf "%s" (tpl .Values.extendedConfConfigMap $) -}} +{{- else -}} +{{- printf "%s-extended-configuration" (include "postgresql.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Get the initialization scripts ConfigMap name. +*/}} +{{- define "postgresql.initdbScriptsCM" -}} +{{- if .Values.initdbScriptsConfigMap -}} +{{- printf "%s" (tpl .Values.initdbScriptsConfigMap $) -}} +{{- else -}} +{{- printf "%s-init-scripts" (include "postgresql.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Get the initialization scripts Secret name. +*/}} +{{- define "postgresql.initdbScriptsSecret" -}} +{{- printf "%s" (tpl .Values.initdbScriptsSecret $) -}} +{{- end -}} + +{{/* +Get the metrics ConfigMap name. +*/}} +{{- define "postgresql.metricsCM" -}} +{{- printf "%s-metrics" (include "postgresql.fullname" .) -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "postgresql.imagePullSecrets" -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. +Also, we can not use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets .Values.volumePermissions.image.pullSecrets }} +imagePullSecrets: +{{- range .Values.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.metrics.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.volumePermissions.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- end -}} +{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets .Values.volumePermissions.image.pullSecrets }} +imagePullSecrets: +{{- range .Values.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.metrics.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.volumePermissions.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- end -}} +{{- end -}} + +{{/* +Get the readiness probe command +*/}} +{{- define "postgresql.readinessProbeCommand" -}} +- | +{{- if (include "postgresql.database" .) }} + exec pg_isready -U {{ include "postgresql.username" . | quote }} -d {{ (include "postgresql.database" .) | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} +{{- else }} + exec pg_isready -U {{ include "postgresql.username" . | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} +{{- end }} +{{- if contains "bitnami/" .Values.image.repository }} + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ] +{{- end -}} +{{- end -}} + +{{/* +Return the proper Storage Class +*/}} +{{- define "postgresql.storageClass" -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. +*/}} +{{- if .Values.global -}} + {{- if .Values.global.storageClass -}} + {{- if (eq "-" .Values.global.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.global.storageClass -}} + {{- end -}} + {{- else -}} + {{- if .Values.persistence.storageClass -}} + {{- if (eq "-" .Values.persistence.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.persistence.storageClass -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- else -}} + {{- if .Values.persistence.storageClass -}} + {{- if (eq "-" .Values.persistence.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.persistence.storageClass -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Renders a value that contains template. +Usage: +{{ include "postgresql.tplValue" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "postgresql.tplValue" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "postgresql.statefulset.apiVersion" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "apps/v1beta2" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Compile all warnings into a single message, and call fail. +*/}} +{{- define "postgresql.validateValues" -}} +{{- $messages := list -}} +{{- $messages := append $messages (include "postgresql.validateValues.ldapConfigurationMethod" .) -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} + +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} + +{{/* +Validate values of Postgresql - If ldap.url is used then you don't need the other settings for ldap +*/}} +{{- define "postgresql.validateValues.ldapConfigurationMethod" -}} +{{- if and .Values.ldap.enabled (and (not (empty .Values.ldap.url)) (not (empty .Values.ldap.server))) }} +postgresql: ldap.url, ldap.server + You cannot set both `ldap.url` and `ldap.server` at the same time. + Please provide a unique way to configure LDAP. + More info at https://www.postgresql.org/docs/current/auth-ldap.html +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/postgresql/templates/configmap.yaml b/infra/charts/feast/charts/postgresql/templates/configmap.yaml new file mode 100644 index 00000000000..d2178c077e5 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/configmap.yaml @@ -0,0 +1,26 @@ +{{ if and (or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration) (not .Values.configurationConfigMap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "postgresql.fullname" . }}-configuration + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +data: +{{- if (.Files.Glob "files/postgresql.conf") }} +{{ (.Files.Glob "files/postgresql.conf").AsConfig | indent 2 }} +{{- else if .Values.postgresqlConfiguration }} + postgresql.conf: | +{{- range $key, $value := default dict .Values.postgresqlConfiguration }} + {{ $key | snakecase }}={{ $value }} +{{- end }} +{{- end }} +{{- if (.Files.Glob "files/pg_hba.conf") }} +{{ (.Files.Glob "files/pg_hba.conf").AsConfig | indent 2 }} +{{- else if .Values.pgHbaConfiguration }} + pg_hba.conf: | +{{ .Values.pgHbaConfiguration | indent 4 }} +{{- end }} +{{ end }} diff --git a/infra/charts/feast/charts/postgresql/templates/extended-config-configmap.yaml b/infra/charts/feast/charts/postgresql/templates/extended-config-configmap.yaml new file mode 100644 index 00000000000..8a411957823 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/extended-config-configmap.yaml @@ -0,0 +1,21 @@ +{{- if and (or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf) (not .Values.extendedConfConfigMap)}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "postgresql.fullname" . }}-extended-configuration + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +data: +{{- with .Files.Glob "files/conf.d/*.conf" }} +{{ .AsConfig | indent 2 }} +{{- end }} +{{ with .Values.postgresqlExtendedConf }} + override.conf: | +{{- range $key, $value := . }} + {{ $key | snakecase }}={{ $value }} +{{- end }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/initialization-configmap.yaml b/infra/charts/feast/charts/postgresql/templates/initialization-configmap.yaml new file mode 100644 index 00000000000..8eb5e05881f --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/initialization-configmap.yaml @@ -0,0 +1,24 @@ +{{- if and (or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScripts) (not .Values.initdbScriptsConfigMap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "postgresql.fullname" . }}-init-scripts + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +{{- with .Files.Glob "files/docker-entrypoint-initdb.d/*.sql.gz" }} +binaryData: +{{- range $path, $bytes := . }} + {{ base $path }}: {{ $.Files.Get $path | b64enc | quote }} +{{- end }} +{{- end }} +data: +{{- with .Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql}" }} +{{ .AsConfig | indent 2 }} +{{- end }} +{{- with .Values.initdbScripts }} +{{ toYaml . | indent 2 }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/metrics-configmap.yaml b/infra/charts/feast/charts/postgresql/templates/metrics-configmap.yaml new file mode 100644 index 00000000000..524aa2f6a94 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/metrics-configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "postgresql.metricsCM" . }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +data: + custom-metrics.yaml: {{ toYaml .Values.metrics.customMetrics | quote }} +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/metrics-svc.yaml b/infra/charts/feast/charts/postgresql/templates/metrics-svc.yaml new file mode 100644 index 00000000000..c610f09aff8 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/metrics-svc.yaml @@ -0,0 +1,26 @@ +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "postgresql.fullname" . }}-metrics + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} + annotations: +{{ toYaml .Values.metrics.service.annotations | indent 4 }} +spec: + type: {{ .Values.metrics.service.type }} + {{- if and (eq .Values.metrics.service.type "LoadBalancer") .Values.metrics.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.metrics.service.loadBalancerIP }} + {{- end }} + ports: + - name: http-metrics + port: 9187 + targetPort: http-metrics + selector: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name }} + role: master +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/networkpolicy.yaml b/infra/charts/feast/charts/postgresql/templates/networkpolicy.yaml new file mode 100644 index 00000000000..ea1fc9b3a22 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/networkpolicy.yaml @@ -0,0 +1,38 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "postgresql.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "postgresql.fullname" . }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +spec: + podSelector: + matchLabels: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name | quote }} + ingress: + # Allow inbound connections + - ports: + - port: {{ template "postgresql.port" . }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "postgresql.fullname" . }}-client: "true" + {{- if .Values.networkPolicy.explicitNamespacesSelector }} + namespaceSelector: +{{ toYaml .Values.networkPolicy.explicitNamespacesSelector | indent 12 }} + {{- end }} + - podSelector: + matchLabels: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name | quote }} + role: slave + {{- end }} + # Allow prometheus scrapes + - ports: + - port: 9187 +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/prometheusrule.yaml b/infra/charts/feast/charts/postgresql/templates/prometheusrule.yaml new file mode 100644 index 00000000000..44f1242dddb --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/prometheusrule.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "postgresql.fullname" . }} +{{- with .Values.metrics.prometheusRule.namespace }} + namespace: {{ . }} +{{- end }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +{{- with .Values.metrics.prometheusRule.additionalLabels }} +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- with .Values.metrics.prometheusRule.rules }} + groups: + - name: {{ template "postgresql.name" $ }} + rules: {{ tpl (toYaml .) $ | nindent 8 }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/secrets.yaml b/infra/charts/feast/charts/postgresql/templates/secrets.yaml new file mode 100644 index 00000000000..094d18b49f8 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/secrets.yaml @@ -0,0 +1,23 @@ +{{- if (include "postgresql.createSecret" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "postgresql.fullname" . }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +type: Opaque +data: + {{- if and .Values.postgresqlPostgresPassword (not (eq .Values.postgresqlUsername "postgres")) }} + postgresql-postgres-password: {{ include "postgresql.postgres.password" . | b64enc | quote }} + {{- end }} + postgresql-password: {{ include "postgresql.password" . | b64enc | quote }} + {{- if .Values.replication.enabled }} + postgresql-replication-password: {{ include "postgresql.replication.password" . | b64enc | quote }} + {{- end }} + {{- if (and .Values.ldap.enabled .Values.ldap.bind_password)}} + postgresql-ldap-password: {{ .Values.ldap.bind_password | b64enc | quote }} + {{- end }} +{{- end -}} diff --git a/infra/charts/feast/charts/postgresql/templates/serviceaccount.yaml b/infra/charts/feast/charts/postgresql/templates/serviceaccount.yaml new file mode 100644 index 00000000000..27e5b516efa --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- if and (.Values.serviceAccount.enabled) (not .Values.serviceAccount.name) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} + name: {{ template "postgresql.fullname" . }} +{{- end }} \ No newline at end of file diff --git a/infra/charts/feast/charts/postgresql/templates/servicemonitor.yaml b/infra/charts/feast/charts/postgresql/templates/servicemonitor.yaml new file mode 100644 index 00000000000..f3a529a9649 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/servicemonitor.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "postgresql.fullname" . }} + {{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} + {{- if .Values.metrics.serviceMonitor.additionalLabels }} +{{ toYaml .Values.metrics.serviceMonitor.additionalLabels | indent 4 }} + {{- end }} +spec: + endpoints: + - port: http-metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/statefulset-slaves.yaml b/infra/charts/feast/charts/postgresql/templates/statefulset-slaves.yaml new file mode 100644 index 00000000000..3290ff7fcd0 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/statefulset-slaves.yaml @@ -0,0 +1,299 @@ +{{- if .Values.replication.enabled }} +apiVersion: {{ template "postgresql.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: "{{ template "postgresql.fullname" . }}-slave" + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +{{- with .Values.slave.labels }} +{{ toYaml . | indent 4 }} +{{- end }} +{{- with .Values.slave.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + serviceName: {{ template "postgresql.fullname" . }}-headless + replicas: {{ .Values.replication.slaveReplicas }} + selector: + matchLabels: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name | quote }} + role: slave + template: + metadata: + name: {{ template "postgresql.fullname" . }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} + role: slave +{{- with .Values.slave.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.slave.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- if .Values.schedulerName }} + schedulerName: "{{ .Values.schedulerName }}" + {{- end }} +{{- include "postgresql.imagePullSecrets" . | indent 6 }} + {{- if .Values.slave.nodeSelector }} + nodeSelector: +{{ toYaml .Values.slave.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.slave.affinity }} + affinity: +{{ toYaml .Values.slave.affinity | indent 8 }} + {{- end }} + {{- if .Values.slave.tolerations }} + tolerations: +{{ toYaml .Values.slave.tolerations | indent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.securityContext.enabled }} + securityContext: + fsGroup: {{ .Values.securityContext.fsGroup }} + {{- end }} + {{- if .Values.serviceAccount.enabled }} + serviceAccountName: {{ default (include "postgresql.fullname" . ) .Values.serviceAccount.name}} + {{- end }} + {{- if or .Values.slave.extraInitContainers (and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled))) }} + initContainers: + {{- if and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled)) }} + - name: init-chmod-data + image: {{ template "postgresql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -cx + - | + {{ if .Values.persistence.enabled }} + mkdir -p {{ .Values.persistence.mountPath }}/data + chmod 700 {{ .Values.persistence.mountPath }}/data + find {{ .Values.persistence.mountPath }} -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | \ + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + xargs chown -R `id -u`:`id -G | cut -d " " -f2` + {{- else }} + xargs chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} + {{- end }} + {{- end }} + {{- if and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled }} + chmod -R 777 /dev/shm + {{- end }} + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + securityContext: + {{- else }} + securityContext: + runAsUser: {{ .Values.volumePermissions.securityContext.runAsUser }} + {{- end }} + volumeMounts: + {{ if .Values.persistence.enabled }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- end }} + {{- if .Values.slave.extraInitContainers }} +{{ tpl .Values.slave.extraInitContainers . | indent 8 }} + {{- end }} + {{- end }} + {{- if .Values.slave.priorityClassName }} + priorityClassName: {{ .Values.slave.priorityClassName }} + {{- end }} + containers: + - name: {{ template "postgresql.fullname" . }} + image: {{ template "postgresql.image" . }} + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + {{- if .Values.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" .Values.image.debug | quote }} + - name: POSTGRESQL_VOLUME_DIR + value: "{{ .Values.persistence.mountPath }}" + - name: POSTGRESQL_PORT_NUMBER + value: "{{ template "postgresql.port" . }}" + {{- if .Values.persistence.mountPath }} + - name: PGDATA + value: {{ .Values.postgresqlDataDir | quote }} + {{- end }} + - name: POSTGRES_REPLICATION_MODE + value: "slave" + - name: POSTGRES_REPLICATION_USER + value: {{ include "postgresql.replication.username" . | quote }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_REPLICATION_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-replication-password" + {{- else }} + - name: POSTGRES_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-replication-password + {{- end }} + - name: POSTGRES_CLUSTER_APP_NAME + value: {{ .Values.replication.applicationName }} + - name: POSTGRES_MASTER_HOST + value: {{ template "postgresql.fullname" . }} + - name: POSTGRES_MASTER_PORT_NUMBER + value: {{ include "postgresql.port" . | quote }} + {{- if and .Values.postgresqlPostgresPassword (not (eq .Values.postgresqlUsername "postgres")) }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-postgres-password" + {{- else }} + - name: POSTGRES_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-postgres-password + {{- end }} + {{- end }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-password" + {{- else }} + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-password + {{- end }} + ports: + - name: tcp-postgresql + containerPort: {{ template "postgresql.port" . }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} -d {{ (include "postgresql.database" .) | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} + {{- else }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} + {{- end }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + exec: + command: + - /bin/sh + - -c + - -e + {{- include "postgresql.readinessProbeCommand" . | nindent 16 }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- end }} + volumeMounts: + {{- if .Values.usePasswordFile }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.persistence.enabled }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + subPath: {{ .Values.persistence.subPath }} + {{ end }} + {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} + - name: postgresql-extended-config + mountPath: /bitnami/postgresql/conf/conf.d/ + {{- end }} + {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} + - name: postgresql-config + mountPath: /bitnami/postgresql/conf + {{- end }} + {{- if .Values.slave.extraVolumeMounts }} + {{- toYaml .Values.slave.extraVolumeMounts | nindent 12 }} + {{- end }} +{{- if .Values.slave.sidecars }} +{{- include "postgresql.tplValue" ( dict "value" .Values.slave.sidecars "context" $ ) | nindent 8 }} +{{- end }} + volumes: + {{- if .Values.usePasswordFile }} + - name: postgresql-password + secret: + secretName: {{ template "postgresql.secretName" . }} + {{- end }} + {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap}} + - name: postgresql-config + configMap: + name: {{ template "postgresql.configurationCM" . }} + {{- end }} + {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} + - name: postgresql-extended-config + configMap: + name: {{ template "postgresql.extendedConfigurationCM" . }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + emptyDir: + medium: Memory + sizeLimit: 1Gi + {{- end }} + {{- if not .Values.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- if .Values.slave.extraVolumes }} + {{- toYaml .Values.slave.extraVolumes | nindent 8 }} + {{- end }} + updateStrategy: + type: {{ .Values.updateStrategy.type }} + {{- if (eq "Recreate" .Values.updateStrategy.type) }} + rollingUpdate: null + {{- end }} +{{- if .Values.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: data + {{- with .Values.persistence.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }} + spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{ include "postgresql.storageClass" . }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/statefulset.yaml b/infra/charts/feast/charts/postgresql/templates/statefulset.yaml new file mode 100644 index 00000000000..3390be22b2b --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/statefulset.yaml @@ -0,0 +1,458 @@ +apiVersion: {{ template "postgresql.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ template "postgresql.master.fullname" . }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +{{- with .Values.master.labels }} +{{ toYaml . | indent 4 }} +{{- end }} +{{- with .Values.master.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + serviceName: {{ template "postgresql.fullname" . }}-headless + replicas: 1 + updateStrategy: + type: {{ .Values.updateStrategy.type }} + {{- if (eq "Recreate" .Values.updateStrategy.type) }} + rollingUpdate: null + {{- end }} + selector: + matchLabels: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name | quote }} + role: master + template: + metadata: + name: {{ template "postgresql.fullname" . }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} + role: master +{{- with .Values.master.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.master.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- if .Values.schedulerName }} + schedulerName: "{{ .Values.schedulerName }}" + {{- end }} +{{- include "postgresql.imagePullSecrets" . | indent 6 }} + {{- if .Values.master.nodeSelector }} + nodeSelector: +{{ toYaml .Values.master.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.master.affinity }} + affinity: +{{ toYaml .Values.master.affinity | indent 8 }} + {{- end }} + {{- if .Values.master.tolerations }} + tolerations: +{{ toYaml .Values.master.tolerations | indent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.securityContext.enabled }} + securityContext: + fsGroup: {{ .Values.securityContext.fsGroup }} + {{- end }} + {{- if .Values.serviceAccount.enabled }} + serviceAccountName: {{ default (include "postgresql.fullname" . ) .Values.serviceAccount.name }} + {{- end }} + {{- if or .Values.master.extraInitContainers (and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled))) }} + initContainers: + {{- if and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled)) }} + - name: init-chmod-data + image: {{ template "postgresql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -cx + - | + {{ if .Values.persistence.enabled }} + mkdir -p {{ .Values.persistence.mountPath }}/data + chmod 700 {{ .Values.persistence.mountPath }}/data + find {{ .Values.persistence.mountPath }} -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | \ + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + xargs chown -R `id -u`:`id -G | cut -d " " -f2` + {{- else }} + xargs chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} + {{- end }} + {{- end }} + {{- if and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled }} + chmod -R 777 /dev/shm + {{- end }} + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + securityContext: + {{- else }} + securityContext: + runAsUser: {{ .Values.volumePermissions.securityContext.runAsUser }} + {{- end }} + volumeMounts: + {{ if .Values.persistence.enabled }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- end }} + {{- if .Values.master.extraInitContainers }} +{{ tpl .Values.master.extraInitContainers . | indent 8 }} + {{- end }} + {{- end }} + {{- if .Values.master.priorityClassName }} + priorityClassName: {{ .Values.master.priorityClassName }} + {{- end }} + containers: + - name: {{ template "postgresql.fullname" . }} + image: {{ template "postgresql.image" . }} + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + {{- if .Values.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" .Values.image.debug | quote }} + - name: POSTGRESQL_PORT_NUMBER + value: "{{ template "postgresql.port" . }}" + - name: POSTGRESQL_VOLUME_DIR + value: "{{ .Values.persistence.mountPath }}" + {{- if .Values.postgresqlInitdbArgs }} + - name: POSTGRES_INITDB_ARGS + value: {{ .Values.postgresqlInitdbArgs | quote }} + {{- end }} + {{- if .Values.postgresqlInitdbWalDir }} + - name: POSTGRES_INITDB_WALDIR + value: {{ .Values.postgresqlInitdbWalDir | quote }} + {{- end }} + {{- if .Values.initdbUser }} + - name: POSTGRESQL_INITSCRIPTS_USERNAME + value: {{ .Values.initdbUser }} + {{- end }} + {{- if .Values.initdbPassword }} + - name: POSTGRESQL_INITSCRIPTS_PASSWORD + value: .Values.initdbPassword + {{- end }} + {{- if .Values.persistence.mountPath }} + - name: PGDATA + value: {{ .Values.postgresqlDataDir | quote }} + {{- end }} + {{- if .Values.replication.enabled }} + - name: POSTGRES_REPLICATION_MODE + value: "master" + - name: POSTGRES_REPLICATION_USER + value: {{ include "postgresql.replication.username" . | quote }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_REPLICATION_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-replication-password" + {{- else }} + - name: POSTGRES_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-replication-password + {{- end }} + {{- if not (eq .Values.replication.synchronousCommit "off")}} + - name: POSTGRES_SYNCHRONOUS_COMMIT_MODE + value: {{ .Values.replication.synchronousCommit | quote }} + - name: POSTGRES_NUM_SYNCHRONOUS_REPLICAS + value: {{ .Values.replication.numSynchronousReplicas | quote }} + {{- end }} + - name: POSTGRES_CLUSTER_APP_NAME + value: {{ .Values.replication.applicationName }} + {{- end }} + {{- if and .Values.postgresqlPostgresPassword (not (eq .Values.postgresqlUsername "postgres")) }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-postgres-password" + {{- else }} + - name: POSTGRES_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-postgres-password + {{- end }} + {{- end }} + - name: POSTGRES_USER + value: {{ include "postgresql.username" . | quote }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-password" + {{- else }} + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-password + {{- end }} + {{- if (include "postgresql.database" .) }} + - name: POSTGRES_DB + value: {{ (include "postgresql.database" .) | quote }} + {{- end }} + {{- if .Values.extraEnv }} + {{- include "postgresql.tplValue" (dict "value" .Values.extraEnv "context" $) | nindent 12 }} + {{- end }} + - name: POSTGRESQL_ENABLE_LDAP + value: {{ ternary "yes" "no" .Values.ldap.enabled | quote }} + {{- if .Values.ldap.enabled }} + - name: POSTGRESQL_LDAP_SERVER + value: {{ .Values.ldap.server }} + - name: POSTGRESQL_LDAP_PORT + value: {{ .Values.ldap.port | quote }} + - name: POSTGRESQL_LDAP_SCHEME + value: {{ .Values.ldap.scheme }} + {{- if .Values.ldap.tls }} + - name: POSTGRESQL_LDAP_TLS + value: "1" + {{- end}} + - name: POSTGRESQL_LDAP_PREFIX + value: {{ .Values.ldap.prefix | quote }} + - name: POSTGRESQL_LDAP_SUFFIX + value: {{ .Values.ldap.suffix | quote}} + - name: POSTGRESQL_LDAP_BASE_DN + value: {{ .Values.ldap.baseDN }} + - name: POSTGRESQL_LDAP_BIND_DN + value: {{ .Values.ldap.bindDN }} + {{- if (not (empty .Values.ldap.bind_password)) }} + - name: POSTGRESQL_LDAP_BIND_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-ldap-password + {{- end}} + - name: POSTGRESQL_LDAP_SEARCH_ATTR + value: {{ .Values.ldap.search_attr }} + - name: POSTGRESQL_LDAP_SEARCH_FILTER + value: {{ .Values.ldap.search_filter }} + - name: POSTGRESQL_LDAP_URL + value: {{ .Values.ldap.url }} + {{- end}} + {{- if .Values.extraEnvVarsCM }} + envFrom: + - configMapRef: + name: {{ .Values.extraEnvVarsCM }} + {{- end }} + ports: + - name: tcp-postgresql + containerPort: {{ template "postgresql.port" . }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} -d {{ (include "postgresql.database" .) | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} + {{- else }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} + {{- end }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + exec: + command: + - /bin/sh + - -c + - -e + {{- include "postgresql.readinessProbeCommand" . | nindent 16 }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- end }} + volumeMounts: + {{- if or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + mountPath: /docker-entrypoint-initdb.d/ + {{- end }} + {{- if .Values.initdbScriptsSecret }} + - name: custom-init-scripts-secret + mountPath: /docker-entrypoint-initdb.d/secret + {{- end }} + {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} + - name: postgresql-extended-config + mountPath: /bitnami/postgresql/conf/conf.d/ + {{- end }} + {{- if .Values.usePasswordFile }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.persistence.enabled }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} + - name: postgresql-config + mountPath: /bitnami/postgresql/conf + {{- end }} + {{- if .Values.master.extraVolumeMounts }} + {{- toYaml .Values.master.extraVolumeMounts | nindent 12 }} + {{- end }} +{{- if .Values.master.sidecars }} +{{- include "postgresql.tplValue" ( dict "value" .Values.master.sidecars "context" $ ) | nindent 8 }} +{{- end }} +{{- if .Values.metrics.enabled }} + - name: metrics + image: {{ template "postgresql.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.metrics.securityContext.runAsUser }} + {{- end }} + env: + {{- $database := required "In order to enable metrics you need to specify a database (.Values.postgresqlDatabase or .Values.global.postgresql.postgresqlDatabase)" (include "postgresql.database" .) }} + - name: DATA_SOURCE_URI + value: {{ printf "127.0.0.1:%d/%s?sslmode=disable" (int (include "postgresql.port" .)) $database | quote }} + {{- if .Values.usePasswordFile }} + - name: DATA_SOURCE_PASS_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-password" + {{- else }} + - name: DATA_SOURCE_PASS + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-password + {{- end }} + - name: DATA_SOURCE_USER + value: {{ template "postgresql.username" . }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: / + port: http-metrics + initialDelaySeconds: {{ .Values.metrics.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.metrics.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.metrics.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.metrics.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.metrics.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: / + port: http-metrics + initialDelaySeconds: {{ .Values.metrics.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.metrics.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.metrics.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.metrics.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.metrics.readinessProbe.failureThreshold }} + {{- end }} + volumeMounts: + {{- if .Values.usePasswordFile }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.metrics.customMetrics }} + - name: custom-metrics + mountPath: /conf + readOnly: true + args: ["--extend.query-path", "/conf/custom-metrics.yaml"] + {{- end }} + ports: + - name: http-metrics + containerPort: 9187 + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- end }} +{{- end }} + volumes: + {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap}} + - name: postgresql-config + configMap: + name: {{ template "postgresql.configurationCM" . }} + {{- end }} + {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} + - name: postgresql-extended-config + configMap: + name: {{ template "postgresql.extendedConfigurationCM" . }} + {{- end }} + {{- if .Values.usePasswordFile }} + - name: postgresql-password + secret: + secretName: {{ template "postgresql.secretName" . }} + {{- end }} + {{- if or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + configMap: + name: {{ template "postgresql.initdbScriptsCM" . }} + {{- end }} + {{- if .Values.initdbScriptsSecret }} + - name: custom-init-scripts-secret + secret: + secretName: {{ template "postgresql.initdbScriptsSecret" . }} + {{- end }} + {{- if .Values.master.extraVolumes }} + {{- toYaml .Values.master.extraVolumes | nindent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} + - name: custom-metrics + configMap: + name: {{ template "postgresql.metricsCM" . }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + emptyDir: + medium: Memory + sizeLimit: 1Gi + {{- end }} +{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }} + - name: data + persistentVolumeClaim: +{{- with .Values.persistence.existingClaim }} + claimName: {{ tpl . $ }} +{{- end }} +{{- else if not .Values.persistence.enabled }} + - name: data + emptyDir: {} +{{- else if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: data + {{- with .Values.persistence.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }} + spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{ include "postgresql.storageClass" . }} +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/svc-headless.yaml b/infra/charts/feast/charts/postgresql/templates/svc-headless.yaml new file mode 100644 index 00000000000..5c71f468d82 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/svc-headless.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "postgresql.fullname" . }}-headless + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: tcp-postgresql + port: {{ template "postgresql.port" . }} + targetPort: tcp-postgresql + selector: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name | quote }} diff --git a/infra/charts/feast/charts/postgresql/templates/svc-read.yaml b/infra/charts/feast/charts/postgresql/templates/svc-read.yaml new file mode 100644 index 00000000000..d9492e2ff3e --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/svc-read.yaml @@ -0,0 +1,31 @@ +{{- if .Values.replication.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "postgresql.fullname" . }}-read + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +{{- with .Values.service.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and .Values.service.loadBalancerIP (eq .Values.service.type "LoadBalancer") }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + ports: + - name: tcp-postgresql + port: {{ template "postgresql.port" . }} + targetPort: tcp-postgresql + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + selector: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name | quote }} + role: slave +{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/svc.yaml b/infra/charts/feast/charts/postgresql/templates/svc.yaml new file mode 100644 index 00000000000..0baea4ac84a --- /dev/null +++ b/infra/charts/feast/charts/postgresql/templates/svc.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "postgresql.fullname" . }} + labels: + app: {{ template "postgresql.name" . }} + chart: {{ template "postgresql.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +{{- with .Values.service.annotations }} + annotations: +{{ tpl (toYaml .) $ | indent 4 }} +{{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and .Values.service.loadBalancerIP (eq .Values.service.type "LoadBalancer") }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{ with .Values.service.loadBalancerSourceRanges }} +{{ toYaml . | indent 4 }} +{{- end }} + {{- end }} + {{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + ports: + - name: tcp-postgresql + port: {{ template "postgresql.port" . }} + targetPort: tcp-postgresql + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + selector: + app: {{ template "postgresql.name" . }} + release: {{ .Release.Name | quote }} + role: master diff --git a/infra/charts/feast/charts/postgresql/values-production.yaml b/infra/charts/feast/charts/postgresql/values-production.yaml new file mode 100644 index 00000000000..8da0b3d93fb --- /dev/null +++ b/infra/charts/feast/charts/postgresql/values-production.yaml @@ -0,0 +1,520 @@ +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +global: + postgresql: {} +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + +## Bitnami PostgreSQL image version +## ref: https://hub.docker.com/r/bitnami/postgresql/tags/ +## +image: + registry: docker.io + repository: bitnami/postgresql + tag: 11.7.0-debian-10-r9 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + + ## Set to true if you would like to see extra information on logs + ## It turns BASH and NAMI debugging in minideb + ## ref: https://github.com/bitnami/minideb-extras/#turn-on-bash-debugging + debug: false + +## String to partially override postgresql.fullname template (will maintain the release name) +## +# nameOverride: + +## String to fully override postgresql.fullname template +## +# fullnameOverride: + +## +## Init containers parameters: +## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup +## +volumePermissions: + enabled: false + image: + registry: docker.io + repository: bitnami/minideb + tag: buster + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + ## Init container Security Context + ## Note: the chown of the data folder is done to securityContext.runAsUser + ## and not the below volumePermissions.securityContext.runAsUser + ## When runAsUser is set to special value "auto", init container will try to chwon the + ## data folder to autodetermined user&group, using commands: `id -u`:`id -G | cut -d" " -f2` + ## "auto" is especially useful for OpenShift which has scc with dynamic userids (and 0 is not allowed). + ## You may want to use this volumePermissions.securityContext.runAsUser="auto" in combination with + ## pod securityContext.enabled=false and shmVolume.chmod.enabled=false + ## + securityContext: + runAsUser: 0 + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: + +## Pod Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +## +securityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + +## Pod Service Account +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +serviceAccount: + enabled: false + ## Name of an already existing service account. Setting this value disables the automatic service account creation. + # name: + +replication: + enabled: true + user: repl_user + password: repl_password + slaveReplicas: 2 + ## Set synchronous commit mode: on, off, remote_apply, remote_write and local + ## ref: https://www.postgresql.org/docs/9.6/runtime-config-wal.html#GUC-WAL-LEVEL + synchronousCommit: "on" + ## From the number of `slaveReplicas` defined above, set the number of those that will have synchronous replication + ## NOTE: It cannot be > slaveReplicas + numSynchronousReplicas: 1 + ## Replication Cluster application name. Useful for defining multiple replication policies + applicationName: my_application + +## PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`) +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-user-on-first-run (see note!) +# postgresqlPostgresPassword: + +## PostgreSQL user (has superuser privileges if username is `postgres`) +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run +postgresqlUsername: postgres + +## PostgreSQL password +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run +## +# postgresqlPassword: + +## PostgreSQL password using existing secret +## existingSecret: secret + +## Mount PostgreSQL secret as a file instead of passing environment variable +# usePasswordFile: false + +## Create a database +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-on-first-run +## +# postgresqlDatabase: + +## PostgreSQL data dir +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +postgresqlDataDir: /bitnami/postgresql/data + +## An array to add extra environment variables +## For example: +## extraEnv: +## - name: FOO +## value: "bar" +## +# extraEnv: +extraEnv: [] + +## Name of a ConfigMap containing extra env vars +## +# extraEnvVarsCM: + +## Specify extra initdb args +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +# postgresqlInitdbArgs: + +## Specify a custom location for the PostgreSQL transaction log +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +# postgresqlInitdbWalDir: + +## PostgreSQL configuration +## Specify runtime configuration parameters as a dict, using camelCase, e.g. +## {"sharedBuffers": "500MB"} +## Alternatively, you can put your postgresql.conf under the files/ directory +## ref: https://www.postgresql.org/docs/current/static/runtime-config.html +## +# postgresqlConfiguration: + +## PostgreSQL extended configuration +## As above, but _appended_ to the main configuration +## Alternatively, you can put your *.conf under the files/conf.d/ directory +## https://github.com/bitnami/bitnami-docker-postgresql#allow-settings-to-be-loaded-from-files-other-than-the-default-postgresqlconf +## +# postgresqlExtendedConf: + +## PostgreSQL client authentication configuration +## Specify content for pg_hba.conf +## Default: do not create pg_hba.conf +## Alternatively, you can put your pg_hba.conf under the files/ directory +# pgHbaConfiguration: |- +# local all all trust +# host all all localhost trust +# host mydatabase mysuser 192.168.0.0/24 md5 + +## ConfigMap with PostgreSQL configuration +## NOTE: This will override postgresqlConfiguration and pgHbaConfiguration +# configurationConfigMap: + +## ConfigMap with PostgreSQL extended configuration +# extendedConfConfigMap: + +## initdb scripts +## Specify dictionary of scripts to be run at first boot +## Alternatively, you can put your scripts under the files/docker-entrypoint-initdb.d directory +## +# initdbScripts: +# my_init_script.sh: | +# #!/bin/sh +# echo "Do something." + +## Specify the PostgreSQL username and password to execute the initdb scripts +# initdbUser: +# initdbPassword: + +## ConfigMap with scripts to be run at first boot +## NOTE: This will override initdbScripts +# initdbScriptsConfigMap: + +## Secret with scripts to be run at first boot (in case it contains sensitive information) +## NOTE: This can work along initdbScripts or initdbScriptsConfigMap +# initdbScriptsSecret: + +## Optional duration in seconds the pod needs to terminate gracefully. +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods +## +# terminationGracePeriodSeconds: 30 + +## LDAP configuration +## +ldap: + enabled: false + url: "" + server: "" + port: "" + prefix: "" + suffix: "" + baseDN: "" + bindDN: "" + bind_password: + search_attr: "" + search_filter: "" + scheme: "" + tls: false + +## PostgreSQL service configuration +service: + ## PosgresSQL service type + type: ClusterIP + # clusterIP: None + port: 5432 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. + ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart + annotations: {} + ## Set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + # loadBalancerIP: + + ## Load Balancer sources + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + # loadBalancerSourceRanges: + # - 10.10.10.0/24 + +## Start master and slave(s) pod(s) without limitations on shm memory. +## By default docker and containerd (and possibly other container runtimes) +## limit `/dev/shm` to `64M` (see e.g. the +## [docker issue](https://github.com/docker-library/postgres/issues/416) and the +## [containerd issue](https://github.com/containerd/containerd/issues/3654), +## which could be not enough if PostgreSQL uses parallel workers heavily. +## +shmVolume: + ## Set `shmVolume.enabled` to `true` to mount a new tmpfs volume to remove + ## this limitation. + ## + enabled: true + ## Set to `true` to `chmod 777 /dev/shm` on a initContainer. + ## This option is ingored if `volumePermissions.enabled` is `false` + ## + chmod: + enabled: true + +## PostgreSQL data Persistent Volume Storage Class +## If defined, storageClassName: +## If set to "-", storageClassName: "", which disables dynamic provisioning +## If undefined (the default) or set to null, no storageClassName spec is +## set, choosing the default provisioner. (gp2 on AWS, standard on +## GKE, AWS & OpenStack) +## +persistence: + enabled: true + ## A manually managed Persistent Volume and Claim + ## If defined, PVC must be created manually before volume will be bound + ## The value is evaluated as a template, so, for example, the name can depend on .Release or .Chart + ## + # existingClaim: + + ## The path the volume will be mounted at, useful when using different + ## PostgreSQL images. + ## + mountPath: /bitnami/postgresql + + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + ## + subPath: "" + + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + annotations: {} + +## updateStrategy for PostgreSQL StatefulSet and its slaves StatefulSets +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies +updateStrategy: + type: RollingUpdate + +## +## PostgreSQL Master parameters +## +master: + ## Node, affinity, tolerations, and priorityclass settings for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption + nodeSelector: {} + affinity: {} + tolerations: [] + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + priorityClassName: "" + ## Additional PostgreSQL Master Volume mounts + ## + extraVolumeMounts: [] + ## Additional PostgreSQL Master Volumes + ## + extraVolumes: [] + ## Add sidecars to the pod + ## + ## For example: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + sidecars: [] + +## +## PostgreSQL Slave parameters +## +slave: + ## Node, affinity, tolerations, and priorityclass settings for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption + nodeSelector: {} + affinity: {} + tolerations: [] + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + priorityClassName: "" + extraInitContainers: | + # - name: do-something + # image: busybox + # command: ['do', 'something'] + ## Additional PostgreSQL Slave Volume mounts + ## + extraVolumeMounts: [] + ## Additional PostgreSQL Slave Volumes + ## + extraVolumes: [] + ## Add sidecars to the pod + ## + ## For example: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + sidecars: [] + +## Configure resource requests and limits +## ref: http://kubernetes.io/docs/user-guide/compute-resources/ +## +resources: + requests: + memory: 256Mi + cpu: 250m + +networkPolicy: + ## Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. + ## + enabled: false + + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to the port PostgreSQL is listening + ## on. When true, PostgreSQL will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + + ## 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 DB. + ## But sometimes, we want the DB 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. + ## + # explicitNamespacesSelector: + # matchLabels: + # role: frontend + # matchExpressions: + # - {key: role, operator: In, values: [frontend]} + +## Configure extra options for liveness and readiness probes +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) +livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + +readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + +## Configure metrics exporter +## +metrics: + enabled: true + # resources: {} + service: + type: ClusterIP + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9187" + loadBalancerIP: + serviceMonitor: + enabled: false + additionalLabels: {} + # namespace: monitoring + # interval: 30s + # scrapeTimeout: 10s + ## Custom PrometheusRule to be defined + ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + prometheusRule: + enabled: false + additionalLabels: {} + namespace: "" + rules: [] + ## These are just examples rules, please adapt them to your needs. + ## Make sure to constraint the rules to the current postgresql service. + # - alert: HugeReplicationLag + # expr: pg_replication_lag{service="{{ template "postgresql.fullname" . }}-metrics"} / 3600 > 1 + # for: 1m + # labels: + # severity: critical + # annotations: + # description: replication for {{ template "postgresql.fullname" . }} PostgreSQL is lagging by {{ "{{ $value }}" }} hour(s). + # summary: PostgreSQL replication is lagging by {{ "{{ $value }}" }} hour(s). + image: + registry: docker.io + repository: bitnami/postgres-exporter + tag: 0.8.0-debian-10-r28 + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + ## Define additional custom metrics + ## ref: https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file + # customMetrics: + # pg_database: + # query: "SELECT d.datname AS name, CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT') THEN pg_catalog.pg_database_size(d.datname) ELSE 0 END AS size FROM pg_catalog.pg_database d where datname not in ('template0', 'template1', 'postgres')" + # metrics: + # - name: + # usage: "LABEL" + # description: "Name of the database" + # - size_bytes: + # usage: "GAUGE" + # description: "Size of the database in bytes" + ## Pod Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## + securityContext: + enabled: false + runAsUser: 1001 + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## Configure extra options for liveness and readiness probes + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 diff --git a/infra/charts/feast/charts/postgresql/values.schema.json b/infra/charts/feast/charts/postgresql/values.schema.json new file mode 100644 index 00000000000..ac2de6e9432 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/values.schema.json @@ -0,0 +1,103 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "postgresqlUsername": { + "type": "string", + "title": "Admin user", + "form": true + }, + "postgresqlPassword": { + "type": "string", + "title": "Password", + "form": true + }, + "persistence": { + "type": "object", + "properties": { + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi" + } + } + }, + "resources": { + "type": "object", + "title": "Required Resources", + "description": "Configure resource requests", + "form": true, + "properties": { + "requests": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "form": true, + "render": "slider", + "title": "Memory Request", + "sliderMin": 10, + "sliderMax": 2048, + "sliderUnit": "Mi" + }, + "cpu": { + "type": "string", + "form": true, + "render": "slider", + "title": "CPU Request", + "sliderMin": 10, + "sliderMax": 2000, + "sliderUnit": "m" + } + } + } + } + }, + "replication": { + "type": "object", + "form": true, + "title": "Replication Details", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable Replication", + "form": true + }, + "slaveReplicas": { + "type": "integer", + "title": "Slave Replicas", + "form": true, + "hidden": { + "condition": false, + "value": "replication.enabled" + } + } + } + }, + "volumePermissions": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable Init Containers", + "description": "Change the owner of the persist volume mountpoint to RunAsUser:fsGroup" + } + } + }, + "metrics": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "Configure metrics exporter", + "form": true + } + } + } + } +} diff --git a/infra/charts/feast/charts/postgresql/values.yaml b/infra/charts/feast/charts/postgresql/values.yaml new file mode 100644 index 00000000000..d336ea03892 --- /dev/null +++ b/infra/charts/feast/charts/postgresql/values.yaml @@ -0,0 +1,526 @@ +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +global: + postgresql: {} +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + +## Bitnami PostgreSQL image version +## ref: https://hub.docker.com/r/bitnami/postgresql/tags/ +## +image: + registry: docker.io + repository: bitnami/postgresql + tag: 11.7.0-debian-10-r9 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + + ## Set to true if you would like to see extra information on logs + ## It turns BASH and NAMI debugging in minideb + ## ref: https://github.com/bitnami/minideb-extras/#turn-on-bash-debugging + debug: false + +## String to partially override postgresql.fullname template (will maintain the release name) +## +# nameOverride: + +## String to fully override postgresql.fullname template +## +# fullnameOverride: + +## +## Init containers parameters: +## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup +## +volumePermissions: + enabled: false + image: + registry: docker.io + repository: bitnami/minideb + tag: buster + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + ## Init container Security Context + ## Note: the chown of the data folder is done to securityContext.runAsUser + ## and not the below volumePermissions.securityContext.runAsUser + ## When runAsUser is set to special value "auto", init container will try to chwon the + ## data folder to autodetermined user&group, using commands: `id -u`:`id -G | cut -d" " -f2` + ## "auto" is especially useful for OpenShift which has scc with dynamic userids (and 0 is not allowed). + ## You may want to use this volumePermissions.securityContext.runAsUser="auto" in combination with + ## pod securityContext.enabled=false and shmVolume.chmod.enabled=false + ## + securityContext: + runAsUser: 0 + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: + + +## Pod Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +## +securityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + +## Pod Service Account +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +serviceAccount: + enabled: false + ## Name of an already existing service account. Setting this value disables the automatic service account creation. + # name: + +replication: + enabled: false + user: repl_user + password: repl_password + slaveReplicas: 1 + ## Set synchronous commit mode: on, off, remote_apply, remote_write and local + ## ref: https://www.postgresql.org/docs/9.6/runtime-config-wal.html#GUC-WAL-LEVEL + synchronousCommit: "off" + ## From the number of `slaveReplicas` defined above, set the number of those that will have synchronous replication + ## NOTE: It cannot be > slaveReplicas + numSynchronousReplicas: 0 + ## Replication Cluster application name. Useful for defining multiple replication policies + applicationName: my_application + +## PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`) +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-user-on-first-run (see note!) +# postgresqlPostgresPassword: + +## PostgreSQL user (has superuser privileges if username is `postgres`) +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run +postgresqlUsername: postgres + +## PostgreSQL password +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run +## +# postgresqlPassword: + +## PostgreSQL password using existing secret +## existingSecret: secret + +## Mount PostgreSQL secret as a file instead of passing environment variable +# usePasswordFile: false + +## Create a database +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-on-first-run +## +# postgresqlDatabase: + +## PostgreSQL data dir +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +postgresqlDataDir: /bitnami/postgresql/data + +## An array to add extra environment variables +## For example: +## extraEnv: +## - name: FOO +## value: "bar" +## +# extraEnv: +extraEnv: [] + +## Name of a ConfigMap containing extra env vars +## +# extraEnvVarsCM: + +## Specify extra initdb args +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +# postgresqlInitdbArgs: + +## Specify a custom location for the PostgreSQL transaction log +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +# postgresqlInitdbWalDir: + +## PostgreSQL configuration +## Specify runtime configuration parameters as a dict, using camelCase, e.g. +## {"sharedBuffers": "500MB"} +## Alternatively, you can put your postgresql.conf under the files/ directory +## ref: https://www.postgresql.org/docs/current/static/runtime-config.html +## +# postgresqlConfiguration: + +## PostgreSQL extended configuration +## As above, but _appended_ to the main configuration +## Alternatively, you can put your *.conf under the files/conf.d/ directory +## https://github.com/bitnami/bitnami-docker-postgresql#allow-settings-to-be-loaded-from-files-other-than-the-default-postgresqlconf +## +# postgresqlExtendedConf: + +## PostgreSQL client authentication configuration +## Specify content for pg_hba.conf +## Default: do not create pg_hba.conf +## Alternatively, you can put your pg_hba.conf under the files/ directory +# pgHbaConfiguration: |- +# local all all trust +# host all all localhost trust +# host mydatabase mysuser 192.168.0.0/24 md5 + +## ConfigMap with PostgreSQL configuration +## NOTE: This will override postgresqlConfiguration and pgHbaConfiguration +# configurationConfigMap: + +## ConfigMap with PostgreSQL extended configuration +# extendedConfConfigMap: + +## initdb scripts +## Specify dictionary of scripts to be run at first boot +## Alternatively, you can put your scripts under the files/docker-entrypoint-initdb.d directory +## +# initdbScripts: +# my_init_script.sh: | +# #!/bin/sh +# echo "Do something." + +## ConfigMap with scripts to be run at first boot +## NOTE: This will override initdbScripts +# initdbScriptsConfigMap: + +## Secret with scripts to be run at first boot (in case it contains sensitive information) +## NOTE: This can work along initdbScripts or initdbScriptsConfigMap +# initdbScriptsSecret: + +## Specify the PostgreSQL username and password to execute the initdb scripts +# initdbUser: +# initdbPassword: + +## Optional duration in seconds the pod needs to terminate gracefully. +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods +## +# terminationGracePeriodSeconds: 30 + +## LDAP configuration +## +ldap: + enabled: false + url: "" + server: "" + port: "" + prefix: "" + suffix: "" + baseDN: "" + bindDN: "" + bind_password: + search_attr: "" + search_filter: "" + scheme: "" + tls: false + +## PostgreSQL service configuration +service: + ## PosgresSQL service type + type: ClusterIP + # clusterIP: None + port: 5432 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. + ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart + annotations: {} + ## Set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + # loadBalancerIP: + + ## Load Balancer sources + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + # loadBalancerSourceRanges: + # - 10.10.10.0/24 + +## Start master and slave(s) pod(s) without limitations on shm memory. +## By default docker and containerd (and possibly other container runtimes) +## limit `/dev/shm` to `64M` (see e.g. the +## [docker issue](https://github.com/docker-library/postgres/issues/416) and the +## [containerd issue](https://github.com/containerd/containerd/issues/3654), +## which could be not enough if PostgreSQL uses parallel workers heavily. +## +shmVolume: + ## Set `shmVolume.enabled` to `true` to mount a new tmpfs volume to remove + ## this limitation. + ## + enabled: true + ## Set to `true` to `chmod 777 /dev/shm` on a initContainer. + ## This option is ingored if `volumePermissions.enabled` is `false` + ## + chmod: + enabled: true + +## PostgreSQL data Persistent Volume Storage Class +## If defined, storageClassName: +## If set to "-", storageClassName: "", which disables dynamic provisioning +## If undefined (the default) or set to null, no storageClassName spec is +## set, choosing the default provisioner. (gp2 on AWS, standard on +## GKE, AWS & OpenStack) +## +persistence: + enabled: true + ## A manually managed Persistent Volume and Claim + ## If defined, PVC must be created manually before volume will be bound + ## The value is evaluated as a template, so, for example, the name can depend on .Release or .Chart + ## + # existingClaim: + + ## The path the volume will be mounted at, useful when using different + ## PostgreSQL images. + ## + mountPath: /bitnami/postgresql + + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + ## + subPath: "" + + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + annotations: {} + +## updateStrategy for PostgreSQL StatefulSet and its slaves StatefulSets +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies +updateStrategy: + type: RollingUpdate + +## +## PostgreSQL Master parameters +## +master: + ## Node, affinity, tolerations, and priorityclass settings for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption + nodeSelector: {} + affinity: {} + tolerations: [] + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + priorityClassName: "" + extraInitContainers: | + # - name: do-something + # image: busybox + # command: ['do', 'something'] + + ## Additional PostgreSQL Master Volume mounts + ## + extraVolumeMounts: [] + ## Additional PostgreSQL Master Volumes + ## + extraVolumes: [] + ## Add sidecars to the pod + ## + ## For example: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + sidecars: [] + +## +## PostgreSQL Slave parameters +## +slave: + ## Node, affinity, tolerations, and priorityclass settings for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption + nodeSelector: {} + affinity: {} + tolerations: [] + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + priorityClassName: "" + extraInitContainers: | + # - name: do-something + # image: busybox + # command: ['do', 'something'] + ## Additional PostgreSQL Slave Volume mounts + ## + extraVolumeMounts: [] + ## Additional PostgreSQL Slave Volumes + ## + extraVolumes: [] + ## Add sidecars to the pod + ## + ## For example: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + sidecars: [] + +## Configure resource requests and limits +## ref: http://kubernetes.io/docs/user-guide/compute-resources/ +## +resources: + requests: + memory: 256Mi + cpu: 250m + +networkPolicy: + ## Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. + ## + enabled: false + + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to the port PostgreSQL is listening + ## on. When true, PostgreSQL will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + + ## 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 DB. + ## But sometimes, we want the DB 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. + ## + # explicitNamespacesSelector: + # matchLabels: + # role: frontend + # matchExpressions: + # - {key: role, operator: In, values: [frontend]} + +## Configure extra options for liveness and readiness probes +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) +livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + +readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + +## Configure metrics exporter +## +metrics: + enabled: false + # resources: {} + service: + type: ClusterIP + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9187" + loadBalancerIP: + serviceMonitor: + enabled: false + additionalLabels: {} + # namespace: monitoring + # interval: 30s + # scrapeTimeout: 10s + ## Custom PrometheusRule to be defined + ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + prometheusRule: + enabled: false + additionalLabels: {} + namespace: "" + rules: [] + ## These are just examples rules, please adapt them to your needs. + ## Make sure to constraint the rules to the current postgresql service. + # - alert: HugeReplicationLag + # expr: pg_replication_lag{service="{{ template "postgresql.fullname" . }}-metrics"} / 3600 > 1 + # for: 1m + # labels: + # severity: critical + # annotations: + # description: replication for {{ template "postgresql.fullname" . }} PostgreSQL is lagging by {{ "{{ $value }}" }} hour(s). + # summary: PostgreSQL replication is lagging by {{ "{{ $value }}" }} hour(s). + image: + registry: docker.io + repository: bitnami/postgres-exporter + tag: 0.8.0-debian-10-r28 + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + ## Define additional custom metrics + ## ref: https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file + # customMetrics: + # pg_database: + # query: "SELECT d.datname AS name, CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT') THEN pg_catalog.pg_database_size(d.datname) ELSE 0 END AS size FROM pg_catalog.pg_database d where datname not in ('template0', 'template1', 'postgres')" + # metrics: + # - name: + # usage: "LABEL" + # description: "Name of the database" + # - size_bytes: + # usage: "GAUGE" + # description: "Size of the database in bytes" + ## Pod Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## + securityContext: + enabled: false + runAsUser: 1001 + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## Configure extra options for liveness and readiness probes + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/.helmignore b/infra/charts/feast/charts/prometheus-statsd-exporter/.helmignore similarity index 100% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/.helmignore rename to infra/charts/feast/charts/prometheus-statsd-exporter/.helmignore diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/Chart.yaml b/infra/charts/feast/charts/prometheus-statsd-exporter/Chart.yaml similarity index 100% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/Chart.yaml rename to infra/charts/feast/charts/prometheus-statsd-exporter/Chart.yaml diff --git a/infra/charts/feast/charts/prometheus-statsd-exporter/README.md b/infra/charts/feast/charts/prometheus-statsd-exporter/README.md new file mode 100644 index 00000000000..af91750df81 --- /dev/null +++ b/infra/charts/feast/charts/prometheus-statsd-exporter/README.md @@ -0,0 +1,49 @@ +prometheus-statsd-exporter +========================== +A Helm chart for prometheus statsd-exporter Scrape metrics stored statsd + +Current chart version is `0.1.2` + +Source code can be found [here](https://github.com/prometheus/statsd_exporter) + + + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"prom/statsd-exporter"` | | +| image.tag | string | `"v0.12.1"` | | +| persistentVolume.accessModes[0] | string | `"ReadWriteOnce"` | | +| persistentVolume.annotations | object | `{}` | | +| persistentVolume.claimName | string | `"prometheus-statsd-exporter"` | | +| persistentVolume.enabled | bool | `true` | | +| persistentVolume.existingClaim | string | `""` | | +| persistentVolume.mountPath | string | `"/data"` | | +| persistentVolume.name | string | `"storage-volume"` | | +| persistentVolume.size | string | `"20Gi"` | | +| persistentVolume.storageClass | object | `{}` | | +| persistentVolume.subPath | string | `""` | | +| service.annotations | object | `{}` | | +| service.clusterIP | string | `""` | | +| service.externalIPs | list | `[]` | | +| service.labels | object | `{}` | | +| service.loadBalancerIP | string | `""` | | +| service.loadBalancerSourceRanges | list | `[]` | | +| service.metricsPort | int | `9102` | | +| service.servicePort | int | `80` | | +| service.statsdPort | int | `9125` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.componentName | string | `"prometheus-statsd-exporter"` | | +| serviceAccount.enable | bool | `false` | | +| statsdexporter.affinity | object | `{}` | | +| statsdexporter.extraArgs | object | `{}` | | +| statsdexporter.ingress.enabled | bool | `false` | | +| statsdexporter.nodeSelector | object | `{}` | | +| statsdexporter.podAnnotations."prometheus.io/path" | string | `"/metrics"` | | +| statsdexporter.podAnnotations."prometheus.io/port" | string | `"9102"` | | +| statsdexporter.podAnnotations."prometheus.io/scrape" | string | `"true"` | | +| statsdexporter.replicaCount | int | `1` | | +| statsdexporter.resources | object | `{}` | | +| statsdexporter.tolerations | object | `{}` | | diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/NOTES.txt b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/NOTES.txt similarity index 100% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/NOTES.txt rename to infra/charts/feast/charts/prometheus-statsd-exporter/templates/NOTES.txt diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/_helpers.tpl b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/_helpers.tpl similarity index 100% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/_helpers.tpl rename to infra/charts/feast/charts/prometheus-statsd-exporter/templates/_helpers.tpl diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/config.yaml b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/config.yaml similarity index 100% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/config.yaml rename to infra/charts/feast/charts/prometheus-statsd-exporter/templates/config.yaml diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/deployment.yaml b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/deployment.yaml similarity index 97% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/deployment.yaml rename to infra/charts/feast/charts/prometheus-statsd-exporter/templates/deployment.yaml index 47308ef89bd..2c36756ca47 100644 --- a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/deployment.yaml +++ b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/deployment.yaml @@ -16,7 +16,7 @@ spec: template: metadata: annotations: -{{ toYaml .Values.statsdexporter.annotations | indent 8 }} +{{ toYaml .Values.statsdexporter.podAnnotations | indent 8 }} labels: app: {{ template "prometheus-statsd-exporter.name" . }} release: {{ .Release.Name }} diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/pvc.yaml b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/pvc.yaml similarity index 100% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/pvc.yaml rename to infra/charts/feast/charts/prometheus-statsd-exporter/templates/pvc.yaml diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/service.yaml b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/service.yaml similarity index 69% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/service.yaml rename to infra/charts/feast/charts/prometheus-statsd-exporter/templates/service.yaml index 88d01b24a61..1690ba7fe09 100644 --- a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/service.yaml +++ b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/service.yaml @@ -15,6 +15,38 @@ metadata: {{ toYaml .Values.service.labels | indent 4 }} {{- end }} name: {{ template "prometheus-statsd-exporter.fullname" . }} +spec: + ports: + - name: metrics + port: {{ .Values.service.metricsPort }} + protocol: TCP + targetPort: 9102 + - name: statsd-tcp + port: {{ .Values.service.statsdPort }} + protocol: TCP + targetPort: 9125 + selector: + app: {{ template "prometheus-statsd-exporter.name" . }} + release: {{ .Release.Name }} + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} + labels: + app: {{ template "prometheus-statsd-exporter.fullname" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version }} + component: "{{ .Chart.Name }}" + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if .Values.service.labels }} +{{ toYaml .Values.service.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus-statsd-exporter.fullname" . }}-udp spec: {{- if .Values.service.clusterIP }} clusterIP: {{ .Values.service.clusterIP }} @@ -33,14 +65,6 @@ spec: {{- end }} {{- end }} ports: - - name: metrics - port: {{ .Values.service.metricsPort }} - protocol: TCP - targetPort: 9102 - - name: statsd-tcp - port: {{ .Values.service.statsdPort }} - protocol: TCP - targetPort: 9125 - name: statsd-udp port: {{ .Values.service.statsdPort }} protocol: UDP diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/serviceaccount.yaml b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/serviceaccount.yaml similarity index 100% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/templates/serviceaccount.yaml rename to infra/charts/feast/charts/prometheus-statsd-exporter/templates/serviceaccount.yaml diff --git a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/values.yaml b/infra/charts/feast/charts/prometheus-statsd-exporter/values.yaml similarity index 96% rename from infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/values.yaml rename to infra/charts/feast/charts/prometheus-statsd-exporter/values.yaml index f2d523771ea..b3f70ee264f 100644 --- a/infra/charts/feast/charts/feast-core/charts/prometheus-statsd-exporter/values.yaml +++ b/infra/charts/feast/charts/prometheus-statsd-exporter/values.yaml @@ -20,6 +20,9 @@ service: statsdexporter: podAnnotations: + prometheus.io/path: /metrics + prometheus.io/port: "9102" + prometheus.io/scrape: "true" extraArgs: {} # - --persistence.file=data-perst diff --git a/infra/charts/feast/charts/feast-serving/.helmignore b/infra/charts/feast/charts/prometheus/.helmignore similarity index 97% rename from infra/charts/feast/charts/feast-serving/.helmignore rename to infra/charts/feast/charts/prometheus/.helmignore index 50af0317254..825c0077915 100644 --- a/infra/charts/feast/charts/feast-serving/.helmignore +++ b/infra/charts/feast/charts/prometheus/.helmignore @@ -19,4 +19,5 @@ .project .idea/ *.tmproj -.vscode/ + +OWNERS diff --git a/infra/charts/feast/charts/prometheus/Chart.yaml b/infra/charts/feast/charts/prometheus/Chart.yaml new file mode 100644 index 00000000000..963d7fc97d8 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/Chart.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +name: prometheus +version: 11.0.2 +appVersion: 2.16.0 +description: Prometheus is a monitoring system and time series database. +home: https://prometheus.io/ +icon: https://raw.githubusercontent.com/prometheus/prometheus.github.io/master/assets/prometheus_logo-cb55bb5c346.png +sources: + - https://github.com/prometheus/alertmanager + - https://github.com/prometheus/prometheus + - https://github.com/prometheus/pushgateway + - https://github.com/prometheus/node_exporter + - https://github.com/kubernetes/kube-state-metrics +maintainers: + - name: gianrubio + email: gianrubio@gmail.com + - name: zanhsieh + email: zanhsieh@gmail.com +engine: gotpl +tillerVersion: ">=2.8.0" diff --git a/infra/charts/feast/charts/prometheus/OWNERS b/infra/charts/feast/charts/prometheus/OWNERS new file mode 100644 index 00000000000..8e4de5ee70e --- /dev/null +++ b/infra/charts/feast/charts/prometheus/OWNERS @@ -0,0 +1,6 @@ +approvers: +- gianrubio +- zanhsieh +reviewers: +- gianrubio +- zanhsieh diff --git a/infra/charts/feast/charts/prometheus/README.md b/infra/charts/feast/charts/prometheus/README.md new file mode 100644 index 00000000000..ff42598cb0f --- /dev/null +++ b/infra/charts/feast/charts/prometheus/README.md @@ -0,0 +1,448 @@ +prometheus +========== +Prometheus is a monitoring system and time series database. + +Current chart version is `11.0.2` + +Source code can be found [here](https://prometheus.io/) + +## Chart Requirements + +| Repository | Name | Version | +|------------|------|---------| +| https://kubernetes-charts.storage.googleapis.com/ | kube-state-metrics | 2.7.* | + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| alertRelabelConfigs | string | `nil` | | +| alertmanager.affinity | object | `{}` | | +| alertmanager.baseURL | string | `"http://localhost:9093"` | | +| alertmanager.configFileName | string | `"alertmanager.yml"` | | +| alertmanager.configFromSecret | string | `""` | | +| alertmanager.configMapOverrideName | string | `""` | | +| alertmanager.enabled | bool | `true` | | +| alertmanager.extraArgs | object | `{}` | | +| alertmanager.extraEnv | object | `{}` | | +| alertmanager.extraSecretMounts | list | `[]` | | +| alertmanager.image.pullPolicy | string | `"IfNotPresent"` | | +| alertmanager.image.repository | string | `"prom/alertmanager"` | | +| alertmanager.image.tag | string | `"v0.20.0"` | | +| alertmanager.ingress.annotations | object | `{}` | | +| alertmanager.ingress.enabled | bool | `false` | | +| alertmanager.ingress.extraLabels | object | `{}` | | +| alertmanager.ingress.extraPaths | list | `[]` | | +| alertmanager.ingress.hosts | list | `[]` | | +| alertmanager.ingress.tls | list | `[]` | | +| alertmanager.name | string | `"alertmanager"` | | +| alertmanager.nodeSelector | object | `{}` | | +| alertmanager.persistentVolume.accessModes[0] | string | `"ReadWriteOnce"` | | +| alertmanager.persistentVolume.annotations | object | `{}` | | +| alertmanager.persistentVolume.enabled | bool | `true` | | +| alertmanager.persistentVolume.existingClaim | string | `""` | | +| alertmanager.persistentVolume.mountPath | string | `"/data"` | | +| alertmanager.persistentVolume.size | string | `"2Gi"` | | +| alertmanager.persistentVolume.subPath | string | `""` | | +| alertmanager.podAnnotations | object | `{}` | | +| alertmanager.podDisruptionBudget.enabled | bool | `false` | | +| alertmanager.podDisruptionBudget.maxUnavailable | int | `1` | | +| alertmanager.podLabels | object | `{}` | | +| alertmanager.podSecurityPolicy.annotations | object | `{}` | | +| alertmanager.prefixURL | string | `""` | | +| alertmanager.priorityClassName | string | `""` | | +| alertmanager.replicaCount | int | `1` | | +| alertmanager.resources | object | `{}` | | +| alertmanager.securityContext.fsGroup | int | `65534` | | +| alertmanager.securityContext.runAsGroup | int | `65534` | | +| alertmanager.securityContext.runAsNonRoot | bool | `true` | | +| alertmanager.securityContext.runAsUser | int | `65534` | | +| alertmanager.service.annotations | object | `{}` | | +| alertmanager.service.clusterIP | string | `""` | | +| alertmanager.service.externalIPs | list | `[]` | | +| alertmanager.service.labels | object | `{}` | | +| alertmanager.service.loadBalancerIP | string | `""` | | +| alertmanager.service.loadBalancerSourceRanges | list | `[]` | | +| alertmanager.service.servicePort | int | `80` | | +| alertmanager.service.sessionAffinity | string | `"None"` | | +| alertmanager.service.type | string | `"ClusterIP"` | | +| alertmanager.statefulSet.enabled | bool | `false` | | +| alertmanager.statefulSet.headless.annotations | object | `{}` | | +| alertmanager.statefulSet.headless.labels | object | `{}` | | +| alertmanager.statefulSet.headless.servicePort | int | `80` | | +| alertmanager.statefulSet.podManagementPolicy | string | `"OrderedReady"` | | +| alertmanager.tolerations | list | `[]` | | +| alertmanagerFiles."alertmanager.yml".global | object | `{}` | | +| alertmanagerFiles."alertmanager.yml".receivers[0].name | string | `"default-receiver"` | | +| alertmanagerFiles."alertmanager.yml".route.group_interval | string | `"5m"` | | +| alertmanagerFiles."alertmanager.yml".route.group_wait | string | `"10s"` | | +| alertmanagerFiles."alertmanager.yml".route.receiver | string | `"default-receiver"` | | +| alertmanagerFiles."alertmanager.yml".route.repeat_interval | string | `"3h"` | | +| configmapReload.alertmanager.enabled | bool | `true` | | +| configmapReload.alertmanager.extraArgs | object | `{}` | | +| configmapReload.alertmanager.extraConfigmapMounts | list | `[]` | | +| configmapReload.alertmanager.extraVolumeDirs | list | `[]` | | +| configmapReload.alertmanager.image.pullPolicy | string | `"IfNotPresent"` | | +| configmapReload.alertmanager.image.repository | string | `"jimmidyson/configmap-reload"` | | +| configmapReload.alertmanager.image.tag | string | `"v0.3.0"` | | +| configmapReload.alertmanager.name | string | `"configmap-reload"` | | +| configmapReload.alertmanager.resources | object | `{}` | | +| configmapReload.prometheus.enabled | bool | `true` | | +| configmapReload.prometheus.extraArgs | object | `{}` | | +| configmapReload.prometheus.extraConfigmapMounts | list | `[]` | | +| configmapReload.prometheus.extraVolumeDirs | list | `[]` | | +| configmapReload.prometheus.image.pullPolicy | string | `"IfNotPresent"` | | +| configmapReload.prometheus.image.repository | string | `"jimmidyson/configmap-reload"` | | +| configmapReload.prometheus.image.tag | string | `"v0.3.0"` | | +| configmapReload.prometheus.name | string | `"configmap-reload"` | | +| configmapReload.prometheus.resources | object | `{}` | | +| extraScrapeConfigs | string | `nil` | | +| imagePullSecrets | string | `nil` | | +| kubeStateMetrics.enabled | bool | `true` | | +| networkPolicy.enabled | bool | `false` | | +| nodeExporter.enabled | bool | `false` | | +| nodeExporter.extraArgs | object | `{}` | | +| nodeExporter.extraConfigmapMounts | list | `[]` | | +| nodeExporter.extraHostPathMounts | list | `[]` | | +| nodeExporter.hostNetwork | bool | `true` | | +| nodeExporter.hostPID | bool | `true` | | +| nodeExporter.image.pullPolicy | string | `"IfNotPresent"` | | +| nodeExporter.image.repository | string | `"prom/node-exporter"` | | +| nodeExporter.image.tag | string | `"v0.18.1"` | | +| nodeExporter.name | string | `"node-exporter"` | | +| nodeExporter.nodeSelector | object | `{}` | | +| nodeExporter.pod.labels | object | `{}` | | +| nodeExporter.podAnnotations | object | `{}` | | +| nodeExporter.podDisruptionBudget.enabled | bool | `false` | | +| nodeExporter.podDisruptionBudget.maxUnavailable | int | `1` | | +| nodeExporter.podSecurityPolicy.annotations | object | `{}` | | +| nodeExporter.priorityClassName | string | `""` | | +| nodeExporter.resources | object | `{}` | | +| nodeExporter.securityContext | object | `{}` | | +| nodeExporter.service.annotations."prometheus.io/scrape" | string | `"true"` | | +| nodeExporter.service.clusterIP | string | `"None"` | | +| nodeExporter.service.externalIPs | list | `[]` | | +| nodeExporter.service.hostPort | int | `9100` | | +| nodeExporter.service.labels | object | `{}` | | +| nodeExporter.service.loadBalancerIP | string | `""` | | +| nodeExporter.service.loadBalancerSourceRanges | list | `[]` | | +| nodeExporter.service.servicePort | int | `9100` | | +| nodeExporter.service.type | string | `"ClusterIP"` | | +| nodeExporter.tolerations | list | `[]` | | +| nodeExporter.updateStrategy.type | string | `"RollingUpdate"` | | +| podSecurityPolicy.enabled | bool | `false` | | +| pushgateway.enabled | bool | `true` | | +| pushgateway.extraArgs | object | `{}` | | +| pushgateway.image.pullPolicy | string | `"IfNotPresent"` | | +| pushgateway.image.repository | string | `"prom/pushgateway"` | | +| pushgateway.image.tag | string | `"v1.0.1"` | | +| pushgateway.ingress.annotations | object | `{}` | | +| pushgateway.ingress.enabled | bool | `false` | | +| pushgateway.ingress.extraPaths | list | `[]` | | +| pushgateway.ingress.hosts | list | `[]` | | +| pushgateway.ingress.tls | list | `[]` | | +| pushgateway.name | string | `"pushgateway"` | | +| pushgateway.nodeSelector | object | `{}` | | +| pushgateway.persistentVolume.accessModes[0] | string | `"ReadWriteOnce"` | | +| pushgateway.persistentVolume.annotations | object | `{}` | | +| pushgateway.persistentVolume.enabled | bool | `false` | | +| pushgateway.persistentVolume.existingClaim | string | `""` | | +| pushgateway.persistentVolume.mountPath | string | `"/data"` | | +| pushgateway.persistentVolume.size | string | `"2Gi"` | | +| pushgateway.persistentVolume.subPath | string | `""` | | +| pushgateway.podAnnotations | object | `{}` | | +| pushgateway.podDisruptionBudget.enabled | bool | `false` | | +| pushgateway.podDisruptionBudget.maxUnavailable | int | `1` | | +| pushgateway.podSecurityPolicy.annotations | object | `{}` | | +| pushgateway.priorityClassName | string | `""` | | +| pushgateway.replicaCount | int | `1` | | +| pushgateway.resources | object | `{}` | | +| pushgateway.securityContext.runAsNonRoot | bool | `true` | | +| pushgateway.securityContext.runAsUser | int | `65534` | | +| pushgateway.service.annotations."prometheus.io/probe" | string | `"pushgateway"` | | +| pushgateway.service.clusterIP | string | `""` | | +| pushgateway.service.externalIPs | list | `[]` | | +| pushgateway.service.labels | object | `{}` | | +| pushgateway.service.loadBalancerIP | string | `""` | | +| pushgateway.service.loadBalancerSourceRanges | list | `[]` | | +| pushgateway.service.servicePort | int | `9091` | | +| pushgateway.service.type | string | `"ClusterIP"` | | +| pushgateway.tolerations | list | `[]` | | +| rbac.create | bool | `true` | | +| server.affinity | object | `{}` | | +| server.alertmanagers | list | `[]` | | +| server.baseURL | string | `""` | | +| server.configMapOverrideName | string | `""` | | +| server.configPath | string | `"/etc/config/prometheus.yml"` | | +| server.emptyDir.sizeLimit | string | `""` | | +| server.enabled | bool | `true` | | +| server.env | list | `[]` | | +| server.extraArgs | object | `{}` | | +| server.extraConfigmapMounts | list | `[]` | | +| server.extraFlags[0] | string | `"web.enable-lifecycle"` | | +| server.extraHostPathMounts | list | `[]` | | +| server.extraInitContainers | list | `[]` | | +| server.extraSecretMounts | list | `[]` | | +| server.extraVolumeMounts | list | `[]` | | +| server.extraVolumes | list | `[]` | | +| server.global.evaluation_interval | string | `"1m"` | | +| server.global.scrape_interval | string | `"1m"` | | +| server.global.scrape_timeout | string | `"10s"` | | +| server.image.pullPolicy | string | `"IfNotPresent"` | | +| server.image.repository | string | `"prom/prometheus"` | | +| server.image.tag | string | `"v2.16.0"` | | +| server.ingress.annotations | object | `{}` | | +| server.ingress.enabled | bool | `false` | | +| server.ingress.extraLabels | object | `{}` | | +| server.ingress.extraPaths | list | `[]` | | +| server.ingress.hosts | list | `[]` | | +| server.ingress.tls | list | `[]` | | +| server.livenessProbeFailureThreshold | int | `3` | | +| server.livenessProbeInitialDelay | int | `30` | | +| server.livenessProbeSuccessThreshold | int | `1` | | +| server.livenessProbeTimeout | int | `30` | | +| server.name | string | `"server"` | | +| server.nodeSelector | object | `{}` | | +| server.persistentVolume.accessModes[0] | string | `"ReadWriteOnce"` | | +| server.persistentVolume.annotations | object | `{}` | | +| server.persistentVolume.enabled | bool | `true` | | +| server.persistentVolume.existingClaim | string | `""` | | +| server.persistentVolume.mountPath | string | `"/data"` | | +| server.persistentVolume.size | string | `"8Gi"` | | +| server.persistentVolume.subPath | string | `""` | | +| server.podAnnotations | object | `{}` | | +| server.podDisruptionBudget.enabled | bool | `false` | | +| server.podDisruptionBudget.maxUnavailable | int | `1` | | +| server.podLabels | object | `{}` | | +| server.podSecurityPolicy.annotations | object | `{}` | | +| server.prefixURL | string | `""` | | +| server.priorityClassName | string | `""` | | +| server.readinessProbeFailureThreshold | int | `3` | | +| server.readinessProbeInitialDelay | int | `30` | | +| server.readinessProbeSuccessThreshold | int | `1` | | +| server.readinessProbeTimeout | int | `30` | | +| server.remoteRead | object | `{}` | | +| server.remoteWrite | object | `{}` | | +| server.replicaCount | int | `1` | | +| server.resources | object | `{}` | | +| server.retention | string | `"15d"` | | +| server.securityContext.fsGroup | int | `65534` | | +| server.securityContext.runAsGroup | int | `65534` | | +| server.securityContext.runAsNonRoot | bool | `true` | | +| server.securityContext.runAsUser | int | `65534` | | +| server.service.annotations | object | `{}` | | +| server.service.clusterIP | string | `""` | | +| server.service.externalIPs | list | `[]` | | +| server.service.gRPC.enabled | bool | `false` | | +| server.service.gRPC.servicePort | int | `10901` | | +| server.service.labels | object | `{}` | | +| server.service.loadBalancerIP | string | `""` | | +| server.service.loadBalancerSourceRanges | list | `[]` | | +| server.service.servicePort | int | `80` | | +| server.service.sessionAffinity | string | `"None"` | | +| server.service.statefulsetReplica.enabled | bool | `false` | | +| server.service.statefulsetReplica.replica | int | `0` | | +| server.service.type | string | `"ClusterIP"` | | +| server.sidecarContainers | string | `nil` | | +| server.statefulSet.annotations | object | `{}` | | +| server.statefulSet.enabled | bool | `false` | | +| server.statefulSet.headless.annotations | object | `{}` | | +| server.statefulSet.headless.labels | object | `{}` | | +| server.statefulSet.headless.servicePort | int | `80` | | +| server.statefulSet.labels | object | `{}` | | +| server.statefulSet.podManagementPolicy | string | `"OrderedReady"` | | +| server.terminationGracePeriodSeconds | int | `300` | | +| server.tolerations | list | `[]` | | +| server.verticalAutoscaler.enabled | bool | `false` | | +| serverFiles."alerting_rules.yml" | object | `{}` | | +| serverFiles."prometheus.yml".rule_files[0] | string | `"/etc/config/recording_rules.yml"` | | +| serverFiles."prometheus.yml".rule_files[1] | string | `"/etc/config/alerting_rules.yml"` | | +| serverFiles."prometheus.yml".rule_files[2] | string | `"/etc/config/rules"` | | +| serverFiles."prometheus.yml".rule_files[3] | string | `"/etc/config/alerts"` | | +| serverFiles."prometheus.yml".scrape_configs[0].job_name | string | `"prometheus"` | | +| serverFiles."prometheus.yml".scrape_configs[0].static_configs[0].targets[0] | string | `"localhost:9090"` | | +| serverFiles."prometheus.yml".scrape_configs[1].bearer_token_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | | +| serverFiles."prometheus.yml".scrape_configs[1].job_name | string | `"kubernetes-apiservers"` | | +| serverFiles."prometheus.yml".scrape_configs[1].kubernetes_sd_configs[0].role | string | `"endpoints"` | | +| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].action | string | `"keep"` | | +| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].regex | string | `"default;kubernetes;https"` | | +| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].source_labels[1] | string | `"__meta_kubernetes_service_name"` | | +| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].source_labels[2] | string | `"__meta_kubernetes_endpoint_port_name"` | | +| serverFiles."prometheus.yml".scrape_configs[1].scheme | string | `"https"` | | +| serverFiles."prometheus.yml".scrape_configs[1].tls_config.ca_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"` | | +| serverFiles."prometheus.yml".scrape_configs[1].tls_config.insecure_skip_verify | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[2].bearer_token_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | | +| serverFiles."prometheus.yml".scrape_configs[2].job_name | string | `"kubernetes-nodes"` | | +| serverFiles."prometheus.yml".scrape_configs[2].kubernetes_sd_configs[0].role | string | `"node"` | | +| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[0].action | string | `"labelmap"` | | +| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[0].regex | string | `"__meta_kubernetes_node_label_(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[1].replacement | string | `"kubernetes.default.svc:443"` | | +| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[1].target_label | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[2].regex | string | `"(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[2].replacement | string | `"/api/v1/nodes/$1/proxy/metrics"` | | +| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[2].source_labels[0] | string | `"__meta_kubernetes_node_name"` | | +| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[2].target_label | string | `"__metrics_path__"` | | +| serverFiles."prometheus.yml".scrape_configs[2].scheme | string | `"https"` | | +| serverFiles."prometheus.yml".scrape_configs[2].tls_config.ca_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"` | | +| serverFiles."prometheus.yml".scrape_configs[2].tls_config.insecure_skip_verify | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[3].bearer_token_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | | +| serverFiles."prometheus.yml".scrape_configs[3].job_name | string | `"kubernetes-nodes-cadvisor"` | | +| serverFiles."prometheus.yml".scrape_configs[3].kubernetes_sd_configs[0].role | string | `"node"` | | +| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[0].action | string | `"labelmap"` | | +| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[0].regex | string | `"__meta_kubernetes_node_label_(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[1].replacement | string | `"kubernetes.default.svc:443"` | | +| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[1].target_label | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[2].regex | string | `"(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[2].replacement | string | `"/api/v1/nodes/$1/proxy/metrics/cadvisor"` | | +| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[2].source_labels[0] | string | `"__meta_kubernetes_node_name"` | | +| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[2].target_label | string | `"__metrics_path__"` | | +| serverFiles."prometheus.yml".scrape_configs[3].scheme | string | `"https"` | | +| serverFiles."prometheus.yml".scrape_configs[3].tls_config.ca_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"` | | +| serverFiles."prometheus.yml".scrape_configs[3].tls_config.insecure_skip_verify | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[4].job_name | string | `"kubernetes-service-endpoints"` | | +| serverFiles."prometheus.yml".scrape_configs[4].kubernetes_sd_configs[0].role | string | `"endpoints"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[0].action | string | `"keep"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[0].regex | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_scrape"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[1].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[1].regex | string | `"(https?)"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[1].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_scheme"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[1].target_label | string | `"__scheme__"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[2].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[2].regex | string | `"(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[2].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_path"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[2].target_label | string | `"__metrics_path__"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].regex | string | `"([^:]+)(?::\\d+)?;(\\d+)"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].replacement | string | `"$1:$2"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].source_labels[0] | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].source_labels[1] | string | `"__meta_kubernetes_service_annotation_prometheus_io_port"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].target_label | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[4].action | string | `"labelmap"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[4].regex | string | `"__meta_kubernetes_service_label_(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[5].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[5].target_label | string | `"kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[6].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[6].source_labels[0] | string | `"__meta_kubernetes_service_name"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[6].target_label | string | `"kubernetes_name"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[7].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[7].source_labels[0] | string | `"__meta_kubernetes_pod_node_name"` | | +| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[7].target_label | string | `"kubernetes_node"` | | +| serverFiles."prometheus.yml".scrape_configs[5].job_name | string | `"kubernetes-service-endpoints-slow"` | | +| serverFiles."prometheus.yml".scrape_configs[5].kubernetes_sd_configs[0].role | string | `"endpoints"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[0].action | string | `"keep"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[0].regex | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_scrape_slow"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[1].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[1].regex | string | `"(https?)"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[1].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_scheme"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[1].target_label | string | `"__scheme__"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[2].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[2].regex | string | `"(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[2].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_path"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[2].target_label | string | `"__metrics_path__"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].regex | string | `"([^:]+)(?::\\d+)?;(\\d+)"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].replacement | string | `"$1:$2"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].source_labels[0] | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].source_labels[1] | string | `"__meta_kubernetes_service_annotation_prometheus_io_port"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].target_label | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[4].action | string | `"labelmap"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[4].regex | string | `"__meta_kubernetes_service_label_(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[5].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[5].target_label | string | `"kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[6].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[6].source_labels[0] | string | `"__meta_kubernetes_service_name"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[6].target_label | string | `"kubernetes_name"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[7].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[7].source_labels[0] | string | `"__meta_kubernetes_pod_node_name"` | | +| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[7].target_label | string | `"kubernetes_node"` | | +| serverFiles."prometheus.yml".scrape_configs[5].scrape_interval | string | `"5m"` | | +| serverFiles."prometheus.yml".scrape_configs[5].scrape_timeout | string | `"30s"` | | +| serverFiles."prometheus.yml".scrape_configs[6].honor_labels | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[6].job_name | string | `"prometheus-pushgateway"` | | +| serverFiles."prometheus.yml".scrape_configs[6].kubernetes_sd_configs[0].role | string | `"service"` | | +| serverFiles."prometheus.yml".scrape_configs[6].relabel_configs[0].action | string | `"keep"` | | +| serverFiles."prometheus.yml".scrape_configs[6].relabel_configs[0].regex | string | `"pushgateway"` | | +| serverFiles."prometheus.yml".scrape_configs[6].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_probe"` | | +| serverFiles."prometheus.yml".scrape_configs[7].job_name | string | `"kubernetes-services"` | | +| serverFiles."prometheus.yml".scrape_configs[7].kubernetes_sd_configs[0].role | string | `"service"` | | +| serverFiles."prometheus.yml".scrape_configs[7].metrics_path | string | `"/probe"` | | +| serverFiles."prometheus.yml".scrape_configs[7].params.module[0] | string | `"http_2xx"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[0].action | string | `"keep"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[0].regex | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_probe"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[1].source_labels[0] | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[1].target_label | string | `"__param_target"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[2].replacement | string | `"blackbox"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[2].target_label | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[3].source_labels[0] | string | `"__param_target"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[3].target_label | string | `"instance"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[4].action | string | `"labelmap"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[4].regex | string | `"__meta_kubernetes_service_label_(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[5].target_label | string | `"kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[6].source_labels[0] | string | `"__meta_kubernetes_service_name"` | | +| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[6].target_label | string | `"kubernetes_name"` | | +| serverFiles."prometheus.yml".scrape_configs[8].job_name | string | `"kubernetes-pods"` | | +| serverFiles."prometheus.yml".scrape_configs[8].kubernetes_sd_configs[0].role | string | `"pod"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[0].action | string | `"keep"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[0].regex | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_scrape"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[1].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[1].regex | string | `"(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[1].source_labels[0] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_path"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[1].target_label | string | `"__metrics_path__"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].regex | string | `"([^:]+)(?::\\d+)?;(\\d+)"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].replacement | string | `"$1:$2"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].source_labels[0] | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].source_labels[1] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_port"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].target_label | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[3].action | string | `"labelmap"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[3].regex | string | `"__meta_kubernetes_pod_label_(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[4].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[4].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[4].target_label | string | `"kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[5].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_pod_name"` | | +| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[5].target_label | string | `"kubernetes_pod_name"` | | +| serverFiles."prometheus.yml".scrape_configs[9].job_name | string | `"kubernetes-pods-slow"` | | +| serverFiles."prometheus.yml".scrape_configs[9].kubernetes_sd_configs[0].role | string | `"pod"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[0].action | string | `"keep"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[0].regex | bool | `true` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_scrape_slow"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[1].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[1].regex | string | `"(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[1].source_labels[0] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_path"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[1].target_label | string | `"__metrics_path__"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].regex | string | `"([^:]+)(?::\\d+)?;(\\d+)"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].replacement | string | `"$1:$2"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].source_labels[0] | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].source_labels[1] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_port"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].target_label | string | `"__address__"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[3].action | string | `"labelmap"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[3].regex | string | `"__meta_kubernetes_pod_label_(.+)"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[4].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[4].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[4].target_label | string | `"kubernetes_namespace"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[5].action | string | `"replace"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_pod_name"` | | +| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[5].target_label | string | `"kubernetes_pod_name"` | | +| serverFiles."prometheus.yml".scrape_configs[9].scrape_interval | string | `"5m"` | | +| serverFiles."prometheus.yml".scrape_configs[9].scrape_timeout | string | `"30s"` | | +| serverFiles."recording_rules.yml" | object | `{}` | | +| serverFiles.alerts | object | `{}` | | +| serverFiles.rules | object | `{}` | | +| serviceAccounts.alertmanager.create | bool | `true` | | +| serviceAccounts.alertmanager.name | string | `nil` | | +| serviceAccounts.nodeExporter.create | bool | `true` | | +| serviceAccounts.nodeExporter.name | string | `nil` | | +| serviceAccounts.pushgateway.create | bool | `true` | | +| serviceAccounts.pushgateway.name | string | `nil` | | +| serviceAccounts.server.create | bool | `true` | | +| serviceAccounts.server.name | string | `nil` | | diff --git a/infra/charts/feast/charts/prometheus/requirements.yaml b/infra/charts/feast/charts/prometheus/requirements.yaml new file mode 100644 index 00000000000..6e079ae7d81 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/requirements.yaml @@ -0,0 +1,7 @@ +dependencies: + + - name: kube-state-metrics + version: "2.7.*" + repository: https://kubernetes-charts.storage.googleapis.com/ + condition: kubeStateMetrics.enabled + diff --git a/infra/charts/feast/charts/prometheus/templates/NOTES.txt b/infra/charts/feast/charts/prometheus/templates/NOTES.txt new file mode 100644 index 00000000000..0e8868f0b72 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/NOTES.txt @@ -0,0 +1,112 @@ +{{- if .Values.server.enabled -}} +The Prometheus server can be accessed via port {{ .Values.server.service.servicePort }} on the following DNS name from within your cluster: +{{ template "prometheus.server.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + +{{ if .Values.server.ingress.enabled -}} +From outside the cluster, the server URL(s) are: +{{- range .Values.server.ingress.hosts }} +http://{{ . }} +{{- end }} +{{- else }} +Get the Prometheus server URL by running these commands in the same shell: +{{- if contains "NodePort" .Values.server.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.server.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.server.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 {{ .Release.Namespace }} -w {{ template "prometheus.server.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.server.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.server.service.servicePort }} +{{- else if contains "ClusterIP" .Values.server.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.server.name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9090 +{{- end }} +{{- end }} + +{{- if .Values.server.persistentVolume.enabled }} +{{- else }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Server pod is terminated. ##### +################################################################################# +{{- end }} +{{- end }} + +{{ if .Values.alertmanager.enabled }} +The Prometheus alertmanager can be accessed via port {{ .Values.alertmanager.service.servicePort }} on the following DNS name from within your cluster: +{{ template "prometheus.alertmanager.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + +{{ if .Values.alertmanager.ingress.enabled -}} +From outside the cluster, the alertmanager URL(s) are: +{{- range .Values.alertmanager.ingress.hosts }} +http://{{ . }} +{{- end }} +{{- else }} +Get the Alertmanager URL by running these commands in the same shell: +{{- if contains "NodePort" .Values.alertmanager.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.alertmanager.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.alertmanager.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 {{ .Release.Namespace }} -w {{ template "prometheus.alertmanager.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.alertmanager.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.alertmanager.service.servicePort }} +{{- else if contains "ClusterIP" .Values.alertmanager.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.alertmanager.name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9093 +{{- end }} +{{- end }} + +{{- if .Values.alertmanager.persistentVolume.enabled }} +{{- else }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the AlertManager pod is terminated. ##### +################################################################################# +{{- end }} +{{- end }} + +{{- if .Values.nodeExporter.podSecurityPolicy.enabled }} +{{- else }} +################################################################################# +###### WARNING: Pod Security Policy has been moved to a global property. ##### +###### use .Values.podSecurityPolicy.enabled with pod-based ##### +###### annotations ##### +###### (e.g. .Values.nodeExporter.podSecurityPolicy.annotations) ##### +################################################################################# +{{- end }} + +{{ if .Values.pushgateway.enabled }} +The Prometheus PushGateway can be accessed via port {{ .Values.pushgateway.service.servicePort }} on the following DNS name from within your cluster: +{{ template "prometheus.pushgateway.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + +{{ if .Values.pushgateway.ingress.enabled -}} +From outside the cluster, the pushgateway URL(s) are: +{{- range .Values.pushgateway.ingress.hosts }} +http://{{ . }} +{{- end }} +{{- else }} +Get the PushGateway URL by running these commands in the same shell: +{{- if contains "NodePort" .Values.pushgateway.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.pushgateway.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.pushgateway.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 {{ .Release.Namespace }} -w {{ template "prometheus.pushgateway.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.pushgateway.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.pushgateway.service.servicePort }} +{{- else if contains "ClusterIP" .Values.pushgateway.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.pushgateway.name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9091 +{{- end }} +{{- end }} +{{- end }} + +For more information on running Prometheus, visit: +https://prometheus.io/ diff --git a/infra/charts/feast/charts/prometheus/templates/_helpers.tpl b/infra/charts/feast/charts/prometheus/templates/_helpers.tpl new file mode 100644 index 00000000000..295aa01c509 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/_helpers.tpl @@ -0,0 +1,276 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "prometheus.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "prometheus.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create unified labels for prometheus components +*/}} +{{- define "prometheus.common.matchLabels" -}} +app: {{ template "prometheus.name" . }} +release: {{ .Release.Name }} +{{- end -}} + +{{- define "prometheus.common.metaLabels" -}} +chart: {{ template "prometheus.chart" . }} +heritage: {{ .Release.Service }} +{{- end -}} + +{{- define "prometheus.alertmanager.labels" -}} +{{ include "prometheus.alertmanager.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.alertmanager.matchLabels" -}} +component: {{ .Values.alertmanager.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- end -}} + +{{- define "prometheus.kubeStateMetrics.labels" -}} +{{ include "prometheus.kubeStateMetrics.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.kubeStateMetrics.matchLabels" -}} +component: {{ .Values.kubeStateMetrics.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- end -}} + +{{- define "prometheus.nodeExporter.labels" -}} +{{ include "prometheus.nodeExporter.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.nodeExporter.matchLabels" -}} +component: {{ .Values.nodeExporter.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- end -}} + +{{- define "prometheus.pushgateway.labels" -}} +{{ include "prometheus.pushgateway.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.pushgateway.matchLabels" -}} +component: {{ .Values.pushgateway.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- end -}} + +{{- define "prometheus.server.labels" -}} +{{ include "prometheus.server.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.server.matchLabels" -}} +component: {{ .Values.server.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- 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). +*/}} +{{- define "prometheus.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified alertmanager name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} + +{{- define "prometheus.alertmanager.fullname" -}} +{{- if .Values.alertmanager.fullnameOverride -}} +{{- .Values.alertmanager.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.alertmanager.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.alertmanager.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified kube-state-metrics name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "prometheus.kubeStateMetrics.fullname" -}} +{{- if .Values.kubeStateMetrics.fullnameOverride -}} +{{- .Values.kubeStateMetrics.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.kubeStateMetrics.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.kubeStateMetrics.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified node-exporter name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "prometheus.nodeExporter.fullname" -}} +{{- if .Values.nodeExporter.fullnameOverride -}} +{{- .Values.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.nodeExporter.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.nodeExporter.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified Prometheus server name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "prometheus.server.fullname" -}} +{{- if .Values.server.fullnameOverride -}} +{{- .Values.server.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.server.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.server.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified pushgateway name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "prometheus.pushgateway.fullname" -}} +{{- if .Values.pushgateway.fullnameOverride -}} +{{- .Values.pushgateway.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.pushgateway.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.pushgateway.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "prometheus.deployment.apiVersion" -}} +{{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "^1.9-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} +{{/* +Return the appropriate apiVersion for daemonset. +*/}} +{{- define "prometheus.daemonset.apiVersion" -}} +{{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "^1.9-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "prometheus.networkPolicy.apiVersion" -}} +{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "^1.7-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} +{{/* +Return the appropriate apiVersion for podsecuritypolicy. +*/}} +{{- define "prometheus.podSecurityPolicy.apiVersion" -}} +{{- if semverCompare ">=1.3-0, <1.10-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "^1.10-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "policy/v1beta1" -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the alertmanager component +*/}} +{{- define "prometheus.serviceAccountName.alertmanager" -}} +{{- if .Values.serviceAccounts.alertmanager.create -}} + {{ default (include "prometheus.alertmanager.fullname" .) .Values.serviceAccounts.alertmanager.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.alertmanager.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the kubeStateMetrics component +*/}} +{{- define "prometheus.serviceAccountName.kubeStateMetrics" -}} +{{- if .Values.serviceAccounts.kubeStateMetrics.create -}} + {{ default (include "prometheus.kubeStateMetrics.fullname" .) .Values.serviceAccounts.kubeStateMetrics.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.kubeStateMetrics.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the nodeExporter component +*/}} +{{- define "prometheus.serviceAccountName.nodeExporter" -}} +{{- if .Values.serviceAccounts.nodeExporter.create -}} + {{ default (include "prometheus.nodeExporter.fullname" .) .Values.serviceAccounts.nodeExporter.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.nodeExporter.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the pushgateway component +*/}} +{{- define "prometheus.serviceAccountName.pushgateway" -}} +{{- if .Values.serviceAccounts.pushgateway.create -}} + {{ default (include "prometheus.pushgateway.fullname" .) .Values.serviceAccounts.pushgateway.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.pushgateway.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the server component +*/}} +{{- define "prometheus.serviceAccountName.server" -}} +{{- if .Values.serviceAccounts.server.create -}} + {{ default (include "prometheus.server.fullname" .) .Values.serviceAccounts.server.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.server.name }} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrole.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrole.yaml new file mode 100644 index 00000000000..3cfc13300b2 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrole.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.alertmanager.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +rules: +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: + - extensions + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "prometheus.alertmanager.fullname" . }} +{{- else }} + [] +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrolebinding.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrolebinding.yaml new file mode 100644 index 00000000000..925afcd3331 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.alertmanager.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.alertmanager" . }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "prometheus.alertmanager.fullname" . }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-configmap.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-configmap.yaml new file mode 100644 index 00000000000..6f6efcece92 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-configmap.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.alertmanager.enabled (and (empty .Values.alertmanager.configMapOverrideName) (empty .Values.alertmanager.configFromSecret)) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +data: +{{- $root := . -}} +{{- range $key, $value := .Values.alertmanagerFiles }} + {{- if $key | regexMatch ".*\\.ya?ml$" }} + {{ $key }}: | +{{ toYaml $value | default "{}" | indent 4 }} + {{- else }} + {{ $key }}: {{ toYaml $value | indent 4 }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-deployment.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-deployment.yaml new file mode 100644 index 00000000000..16ff6695043 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-deployment.yaml @@ -0,0 +1,142 @@ +{{- if and .Values.alertmanager.enabled (not .Values.alertmanager.statefulSet.enabled) -}} +apiVersion: {{ template "prometheus.deployment.apiVersion" . }} +kind: Deployment +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +spec: + selector: + matchLabels: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} + replicas: {{ .Values.alertmanager.replicaCount }} + {{- if .Values.alertmanager.strategy }} + strategy: +{{ toYaml .Values.alertmanager.strategy | indent 4 }} + {{- if eq .Values.alertmanager.strategy.type "Recreate" }} + rollingUpdate: null + {{- end }} + {{- end }} + template: + metadata: + {{- if .Values.alertmanager.podAnnotations }} + annotations: +{{ toYaml .Values.alertmanager.podAnnotations | indent 8 }} + {{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 8 }} + {{- if .Values.alertmanager.podLabels}} + {{ toYaml .Values.alertmanager.podLabels | nindent 8 }} + {{- end}} + spec: +{{- if .Values.alertmanager.schedulerName }} + schedulerName: "{{ .Values.alertmanager.schedulerName }}" +{{- end }} + serviceAccountName: {{ template "prometheus.serviceAccountName.alertmanager" . }} +{{- if .Values.alertmanager.priorityClassName }} + priorityClassName: "{{ .Values.alertmanager.priorityClassName }}" +{{- end }} + containers: + - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }} + image: "{{ .Values.alertmanager.image.repository }}:{{ .Values.alertmanager.image.tag }}" + imagePullPolicy: "{{ .Values.alertmanager.image.pullPolicy }}" + env: + {{- range $key, $value := .Values.alertmanager.extraEnv }} + - name: {{ $key }} + value: {{ $value }} + {{- end }} + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + args: + - --config.file=/etc/config/{{ .Values.alertmanager.configFileName }} + - --storage.path={{ .Values.alertmanager.persistentVolume.mountPath }} + - --cluster.advertise-address=$(POD_IP):6783 + {{- range $key, $value := .Values.alertmanager.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- if .Values.alertmanager.baseURL }} + - --web.external-url={{ .Values.alertmanager.baseURL }} + {{- end }} + + ports: + - containerPort: 9093 + readinessProbe: + httpGet: + path: {{ .Values.alertmanager.prefixURL }}/-/ready + port: 9093 + initialDelaySeconds: 30 + timeoutSeconds: 30 + resources: +{{ toYaml .Values.alertmanager.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: "{{ .Values.alertmanager.persistentVolume.mountPath }}" + subPath: "{{ .Values.alertmanager.persistentVolume.subPath }}" + {{- range .Values.alertmanager.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + + {{- if .Values.configmapReload.alertmanager.enabled }} + - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }}-{{ .Values.configmapReload.alertmanager.name }} + image: "{{ .Values.configmapReload.alertmanager.image.repository }}:{{ .Values.configmapReload.alertmanager.image.tag }}" + imagePullPolicy: "{{ .Values.configmapReload.alertmanager.image.pullPolicy }}" + args: + - --volume-dir=/etc/config + - --webhook-url=http://127.0.0.1:9093{{ .Values.alertmanager.prefixURL }}/-/reload + resources: +{{ toYaml .Values.configmapReload.alertmanager.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{ toYaml .Values.imagePullSecrets | indent 2 }} + {{- end }} + {{- if .Values.alertmanager.nodeSelector }} + nodeSelector: +{{ toYaml .Values.alertmanager.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.securityContext }} + securityContext: +{{ toYaml .Values.alertmanager.securityContext | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.tolerations }} + tolerations: +{{ toYaml .Values.alertmanager.tolerations | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.affinity }} + affinity: +{{ toYaml .Values.alertmanager.affinity | indent 8 }} + {{- end }} + volumes: + - name: config-volume + {{- if empty .Values.alertmanager.configFromSecret }} + configMap: + name: {{ if .Values.alertmanager.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.alertmanager.configMapOverrideName }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} + {{- else }} + secret: + secretName: {{ .Values.alertmanager.configFromSecret }} + {{- end }} + {{- range .Values.alertmanager.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} + - name: storage-volume + {{- if .Values.alertmanager.persistentVolume.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.alertmanager.persistentVolume.existingClaim }}{{ .Values.alertmanager.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} + {{- else }} + emptyDir: {} + {{- end -}} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-ingress.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-ingress.yaml new file mode 100644 index 00000000000..9883054fb97 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-ingress.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.ingress.enabled -}} +{{- $releaseName := .Release.Name -}} +{{- $serviceName := include "prometheus.alertmanager.fullname" . }} +{{- $servicePort := .Values.alertmanager.service.servicePort -}} +{{- $extraPaths := .Values.alertmanager.ingress.extraPaths -}} +{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +apiVersion: networking.k8s.io/v1beta1 +{{ else }} +apiVersion: extensions/v1beta1 +{{ end -}} +kind: Ingress +metadata: +{{- if .Values.alertmanager.ingress.annotations }} + annotations: +{{ toYaml .Values.alertmanager.ingress.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +{{- range $key, $value := .Values.alertmanager.ingress.extraLabels }} + {{ $key }}: {{ $value }} +{{- end }} + name: {{ template "prometheus.alertmanager.fullname" . }} +spec: + rules: + {{- range .Values.alertmanager.ingress.hosts }} + {{- $url := splitList "/" . }} + - host: {{ first $url }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: /{{ rest $url | join "/" }} + backend: + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end -}} +{{- if .Values.alertmanager.ingress.tls }} + tls: +{{ toYaml .Values.alertmanager.ingress.tls | indent 4 }} + {{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-networkpolicy.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-networkpolicy.yaml new file mode 100644 index 00000000000..0bcbd27d410 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-networkpolicy.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.alertmanager.enabled .Values.networkPolicy.enabled -}} +apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ template "prometheus.alertmanager.fullname" . }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} + ingress: + - from: + - podSelector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 12 }} + - ports: + - port: 9093 +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-pdb.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-pdb.yaml new file mode 100644 index 00000000000..c38df77a772 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-pdb.yaml @@ -0,0 +1,13 @@ +{{- if .Values.alertmanager.podDisruptionBudget.enabled }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "prometheus.alertmanager.fullname" . }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +spec: + maxUnavailable: {{ .Values.alertmanager.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + {{- include "prometheus.alertmanager.labels" . | nindent 6 }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-podsecuritypolicy.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-podsecuritypolicy.yaml new file mode 100644 index 00000000000..70f803336ca --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-podsecuritypolicy.yaml @@ -0,0 +1,48 @@ +{{- if .Values.rbac.create }} +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "prometheus.alertmanager.fullname" . }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + annotations: +{{- if .Values.alertmanager.podSecurityPolicy.annotations }} +{{ toYaml .Values.alertmanager.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'configMap' + - 'persistentVolumeClaim' + - 'emptyDir' + - 'secret' + allowedHostPaths: + - pathPrefix: /etc + readOnly: true + - pathPrefix: {{ .Values.alertmanager.persistentVolume.mountPath }} + hostNetwork: false + hostPID: false + hostIPC: 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: true +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-pvc.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-pvc.yaml new file mode 100644 index 00000000000..400aba5b467 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-pvc.yaml @@ -0,0 +1,32 @@ +{{- if not .Values.alertmanager.statefulSet.enabled -}} +{{- if and .Values.alertmanager.enabled .Values.alertmanager.persistentVolume.enabled -}} +{{- if not .Values.alertmanager.persistentVolume.existingClaim -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + {{- if .Values.alertmanager.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.alertmanager.persistentVolume.annotations | indent 4 }} + {{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +spec: + accessModes: +{{ toYaml .Values.alertmanager.persistentVolume.accessModes | indent 4 }} +{{- if .Values.alertmanager.persistentVolume.storageClass }} +{{- if (eq "-" .Values.alertmanager.persistentVolume.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.alertmanager.persistentVolume.storageClass }}" +{{- end }} +{{- end }} +{{- if .Values.alertmanager.persistentVolume.volumeBindingMode }} + volumeBindingModeName: "{{ .Values.alertmanager.persistentVolume.volumeBindingMode }}" +{{- end }} + resources: + requests: + storage: "{{ .Values.alertmanager.persistentVolume.size }}" +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-service-headless.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-service-headless.yaml new file mode 100644 index 00000000000..8d619e89179 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-service-headless.yaml @@ -0,0 +1,30 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.statefulSet.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.alertmanager.statefulSet.headless.annotations }} + annotations: +{{ toYaml .Values.alertmanager.statefulSet.headless.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +{{- if .Values.alertmanager.statefulSet.headless.labels }} +{{ toYaml .Values.alertmanager.statefulSet.headless.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.alertmanager.fullname" . }}-headless +spec: + clusterIP: None + ports: + - name: http + port: {{ .Values.alertmanager.statefulSet.headless.servicePort }} + protocol: TCP + targetPort: 9093 +{{- if .Values.alertmanager.statefulSet.headless.enableMeshPeer }} + - name: meshpeer + port: 6783 + protocol: TCP + targetPort: 6783 +{{- end }} + selector: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 4 }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-service.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-service.yaml new file mode 100644 index 00000000000..79196432c1c --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-service.yaml @@ -0,0 +1,52 @@ +{{- if .Values.alertmanager.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.alertmanager.service.annotations }} + annotations: +{{ toYaml .Values.alertmanager.service.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +{{- if .Values.alertmanager.service.labels }} +{{ toYaml .Values.alertmanager.service.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.alertmanager.fullname" . }} +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 }} + ports: + - name: http + port: {{ .Values.alertmanager.service.servicePort }} + protocol: TCP + targetPort: 9093 + {{- if .Values.alertmanager.service.nodePort }} + nodePort: {{ .Values.alertmanager.service.nodePort }} + {{- end }} +{{- if .Values.alertmanager.service.enableMeshPeer }} + - name: meshpeer + port: 6783 + protocol: TCP + targetPort: 6783 +{{- end }} + selector: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 4 }} +{{- if .Values.alertmanager.service.sessionAffinity }} + sessionAffinity: {{ .Values.alertmanager.service.sessionAffinity }} +{{- end }} + type: "{{ .Values.alertmanager.service.type }}" +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-serviceaccount.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-serviceaccount.yaml new file mode 100644 index 00000000000..4ff4558963a --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-serviceaccount.yaml @@ -0,0 +1,8 @@ +{{- if and .Values.alertmanager.enabled .Values.serviceAccounts.alertmanager.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.serviceAccountName.alertmanager" . }} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-statefulset.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-statefulset.yaml new file mode 100644 index 00000000000..1f8272dcfa2 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/alertmanager-statefulset.yaml @@ -0,0 +1,152 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.statefulSet.enabled -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +spec: + serviceName: {{ template "prometheus.alertmanager.fullname" . }}-headless + selector: + matchLabels: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} + replicas: {{ .Values.alertmanager.replicaCount }} + podManagementPolicy: {{ .Values.alertmanager.statefulSet.podManagementPolicy }} + template: + metadata: + {{- if .Values.alertmanager.podAnnotations }} + annotations: +{{ toYaml .Values.alertmanager.podAnnotations | indent 8 }} + {{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 8 }} + spec: +{{- if .Values.alertmanager.affinity }} + affinity: +{{ toYaml .Values.alertmanager.affinity | indent 8 }} +{{- end }} +{{- if .Values.alertmanager.schedulerName }} + schedulerName: "{{ .Values.alertmanager.schedulerName }}" +{{- end }} + serviceAccountName: {{ template "prometheus.serviceAccountName.alertmanager" . }} +{{- if .Values.alertmanager.priorityClassName }} + priorityClassName: "{{ .Values.alertmanager.priorityClassName }}" +{{- end }} + containers: + - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }} + image: "{{ .Values.alertmanager.image.repository }}:{{ .Values.alertmanager.image.tag }}" + imagePullPolicy: "{{ .Values.alertmanager.image.pullPolicy }}" + env: + {{- range $key, $value := .Values.alertmanager.extraEnv }} + - name: {{ $key }} + value: {{ $value }} + {{- end }} + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + args: + - --config.file=/etc/config/alertmanager.yml + - --storage.path={{ .Values.alertmanager.persistentVolume.mountPath }} + - --cluster.advertise-address=$(POD_IP):6783 + {{- if .Values.alertmanager.statefulSet.headless.enableMeshPeer }} + - --cluster.listen-address=0.0.0.0:6783 + {{- range $n := until (.Values.alertmanager.replicaCount | int) }} + - --cluster.peer={{ template "prometheus.alertmanager.fullname" $ }}-{{ $n }}.{{ template "prometheus.alertmanager.fullname" $ }}-headless:6783 + {{- end }} + {{- end }} + {{- range $key, $value := .Values.alertmanager.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- if .Values.alertmanager.baseURL }} + - --web.external-url={{ .Values.alertmanager.baseURL }} + {{- end }} + + ports: + - containerPort: 9093 + readinessProbe: + httpGet: + path: {{ .Values.alertmanager.prefixURL }}/#/status + port: 9093 + initialDelaySeconds: 30 + timeoutSeconds: 30 + resources: +{{ toYaml .Values.alertmanager.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: "{{ .Values.alertmanager.persistentVolume.mountPath }}" + subPath: "{{ .Values.alertmanager.persistentVolume.subPath }}" + {{- range .Values.alertmanager.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- if .Values.configmapReload.alertmanager.enabled }} + - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }}-{{ .Values.configmapReload.alertmanager.name }} + image: "{{ .Values.configmapReload.alertmanager.image.repository }}:{{ .Values.configmapReload.alertmanager.image.tag }}" + imagePullPolicy: "{{ .Values.configmapReload.alertmanager.image.pullPolicy }}" + args: + - --volume-dir=/etc/config + - --webhook-url=http://localhost:9093{{ .Values.alertmanager.prefixURL }}/-/reload + resources: +{{ toYaml .Values.configmapReload.alertmanager.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{ toYaml .Values.imagePullSecrets | indent 2 }} + {{- end }} + {{- if .Values.alertmanager.nodeSelector }} + nodeSelector: +{{ toYaml .Values.alertmanager.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.securityContext }} + securityContext: +{{ toYaml .Values.alertmanager.securityContext | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.tolerations }} + tolerations: +{{ toYaml .Values.alertmanager.tolerations | indent 8 }} + {{- end }} + volumes: + - name: config-volume + configMap: + name: {{ if .Values.alertmanager.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.alertmanager.configMapOverrideName }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} + {{- range .Values.alertmanager.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} +{{- if .Values.alertmanager.persistentVolume.enabled }} + volumeClaimTemplates: + - metadata: + name: storage-volume + {{- if .Values.alertmanager.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.alertmanager.persistentVolume.annotations | indent 10 }} + {{- end }} + spec: + accessModes: +{{ toYaml .Values.alertmanager.persistentVolume.accessModes | indent 10 }} + resources: + requests: + storage: "{{ .Values.alertmanager.persistentVolume.size }}" + {{- if .Values.server.persistentVolume.storageClass }} + {{- if (eq "-" .Values.server.persistentVolume.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.alertmanager.persistentVolume.storageClass }}" + {{- end }} + {{- end }} +{{- else }} + - name: storage-volume + emptyDir: {} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-daemonset.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-daemonset.yaml new file mode 100644 index 00000000000..478f10a9bae --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/node-exporter-daemonset.yaml @@ -0,0 +1,116 @@ +{{- if .Values.nodeExporter.enabled -}} +apiVersion: {{ template "prometheus.daemonset.apiVersion" . }} +kind: DaemonSet +metadata: +{{- if .Values.nodeExporter.deploymentAnnotations }} + annotations: +{{ toYaml .Values.nodeExporter.deploymentAnnotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} + name: {{ template "prometheus.nodeExporter.fullname" . }} +spec: + selector: + matchLabels: + {{- include "prometheus.nodeExporter.matchLabels" . | nindent 6 }} + {{- if .Values.nodeExporter.updateStrategy }} + updateStrategy: +{{ toYaml .Values.nodeExporter.updateStrategy | indent 4 }} + {{- end }} + template: + metadata: + {{- if .Values.nodeExporter.podAnnotations }} + annotations: +{{ toYaml .Values.nodeExporter.podAnnotations | indent 8 }} + {{- end }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 8 }} +{{- if .Values.nodeExporter.pod.labels }} +{{ toYaml .Values.nodeExporter.pod.labels | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ template "prometheus.serviceAccountName.nodeExporter" . }} +{{- if .Values.nodeExporter.priorityClassName }} + priorityClassName: "{{ .Values.nodeExporter.priorityClassName }}" +{{- end }} + containers: + - name: {{ template "prometheus.name" . }}-{{ .Values.nodeExporter.name }} + image: "{{ .Values.nodeExporter.image.repository }}:{{ .Values.nodeExporter.image.tag }}" + imagePullPolicy: "{{ .Values.nodeExporter.image.pullPolicy }}" + args: + - --path.procfs=/host/proc + - --path.sysfs=/host/sys + {{- range $key, $value := .Values.nodeExporter.extraArgs }} + {{- if $value }} + - --{{ $key }}={{ $value }} + {{- else }} + - --{{ $key }} + {{- end }} + {{- end }} + ports: + - name: metrics + containerPort: 9100 + hostPort: {{ .Values.nodeExporter.service.hostPort }} + resources: +{{ toYaml .Values.nodeExporter.resources | indent 12 }} + volumeMounts: + - name: proc + mountPath: /host/proc + readOnly: true + - name: sys + mountPath: /host/sys + readOnly: true + {{- range .Values.nodeExporter.extraHostPathMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- if .mountPropagation }} + mountPropagation: {{ .mountPropagation }} + {{- end }} + {{- end }} + {{- range .Values.nodeExporter.extraConfigmapMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{ toYaml .Values.imagePullSecrets | indent 2 }} + {{- end }} + {{- if .Values.nodeExporter.hostNetwork }} + hostNetwork: true + {{- end }} + {{- if .Values.nodeExporter.hostPID }} + hostPID: true + {{- end }} + {{- if .Values.nodeExporter.tolerations }} + tolerations: +{{ toYaml .Values.nodeExporter.tolerations | indent 8 }} + {{- end }} + {{- if .Values.nodeExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeExporter.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.nodeExporter.securityContext }} + securityContext: +{{ toYaml .Values.nodeExporter.securityContext | indent 8 }} + {{- end }} + volumes: + - name: proc + hostPath: + path: /proc + - name: sys + hostPath: + path: /sys + {{- range .Values.nodeExporter.extraHostPathMounts }} + - name: {{ .name }} + hostPath: + path: {{ .hostPath }} + {{- end }} + {{- range .Values.nodeExporter.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-podsecuritypolicy.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-podsecuritypolicy.yaml new file mode 100644 index 00000000000..825794b4e32 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/node-exporter-podsecuritypolicy.yaml @@ -0,0 +1,55 @@ +{{- if and .Values.nodeExporter.enabled .Values.rbac.create }} +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "prometheus.nodeExporter.fullname" . }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} + annotations: +{{- if .Values.nodeExporter.podSecurityPolicy.annotations }} +{{ toYaml .Values.nodeExporter.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'configMap' + - 'hostPath' + - 'secret' + allowedHostPaths: + - pathPrefix: /proc + readOnly: true + - pathPrefix: /sys + readOnly: true + {{- range .Values.nodeExporter.extraHostPathMounts }} + - pathPrefix: {{ .hostPath }} + readOnly: {{ .readOnly }} + {{- end }} + hostNetwork: {{ .Values.nodeExporter.hostNetwork }} + hostPID: {{ .Values.nodeExporter.hostPID }} + hostIPC: 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 + hostPorts: + - min: 1 + max: 65535 +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-role.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-role.yaml new file mode 100644 index 00000000000..49a6874b37b --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/node-exporter-role.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.nodeExporter.enabled .Values.rbac.create }} +{{- if or (default .Values.nodeExporter.podSecurityPolicy.enabled false) (.Values.podSecurityPolicy.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ template "prometheus.nodeExporter.fullname" . }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} + namespace: {{ .Release.Namespace }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "prometheus.nodeExporter.fullname" . }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-rolebinding.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-rolebinding.yaml new file mode 100644 index 00000000000..e56e5ff4144 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/node-exporter-rolebinding.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.nodeExporter.enabled .Values.rbac.create }} +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "prometheus.nodeExporter.fullname" . }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: {{ template "prometheus.nodeExporter.fullname" . }} + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.nodeExporter" . }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-service.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-service.yaml new file mode 100644 index 00000000000..55c683b6aba --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/node-exporter-service.yaml @@ -0,0 +1,40 @@ +{{- if .Values.nodeExporter.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.nodeExporter.service.annotations }} + annotations: +{{ toYaml .Values.nodeExporter.service.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} +{{- if .Values.nodeExporter.service.labels }} +{{ toYaml .Values.nodeExporter.service.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.nodeExporter.fullname" . }} +spec: +{{- if .Values.nodeExporter.service.clusterIP }} + clusterIP: {{ .Values.nodeExporter.service.clusterIP }} +{{- end }} +{{- if .Values.nodeExporter.service.externalIPs }} + externalIPs: +{{ toYaml .Values.nodeExporter.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.nodeExporter.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.nodeExporter.service.loadBalancerIP }} +{{- end }} +{{- if .Values.nodeExporter.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.nodeExporter.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: metrics + port: {{ .Values.nodeExporter.service.servicePort }} + protocol: TCP + targetPort: 9100 + selector: + {{- include "prometheus.nodeExporter.matchLabels" . | nindent 4 }} + type: "{{ .Values.nodeExporter.service.type }}" +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-serviceaccount.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-serviceaccount.yaml new file mode 100644 index 00000000000..a922b238bf8 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/node-exporter-serviceaccount.yaml @@ -0,0 +1,8 @@ +{{- if and .Values.nodeExporter.enabled .Values.serviceAccounts.nodeExporter.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} + name: {{ template "prometheus.serviceAccountName.nodeExporter" . }} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrole.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrole.yaml new file mode 100644 index 00000000000..f4393c921a5 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrole.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.pushgateway.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +rules: +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: + - extensions + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "prometheus.pushgateway.fullname" . }} +{{- else }} + [] +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrolebinding.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrolebinding.yaml new file mode 100644 index 00000000000..bcbaccb29b0 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.pushgateway.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.pushgateway" . }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "prometheus.pushgateway.fullname" . }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-deployment.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-deployment.yaml new file mode 100644 index 00000000000..a681eda382c --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-deployment.yaml @@ -0,0 +1,100 @@ +{{- if .Values.pushgateway.enabled -}} +apiVersion: {{ template "prometheus.deployment.apiVersion" . }} +kind: Deployment +metadata: + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +spec: + selector: + {{- if .Values.schedulerName }} + schedulerName: "{{ .Values.schedulerName }}" + {{- end }} + matchLabels: + {{- include "prometheus.pushgateway.matchLabels" . | nindent 6 }} + replicas: {{ .Values.pushgateway.replicaCount }} + {{- if .Values.pushgateway.strategy }} + strategy: +{{ toYaml .Values.pushgateway.strategy | indent 4 }} + {{- if eq .Values.pushgateway.strategy.type "Recreate" }} + rollingUpdate: null + {{- end }} + {{- end }} + template: + metadata: + {{- if .Values.pushgateway.podAnnotations }} + annotations: +{{ toYaml .Values.pushgateway.podAnnotations | indent 8 }} + {{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 8 }} + spec: + serviceAccountName: {{ template "prometheus.serviceAccountName.pushgateway" . }} +{{- if .Values.pushgateway.priorityClassName }} + priorityClassName: "{{ .Values.pushgateway.priorityClassName }}" +{{- end }} + containers: + - name: {{ template "prometheus.name" . }}-{{ .Values.pushgateway.name }} + image: "{{ .Values.pushgateway.image.repository }}:{{ .Values.pushgateway.image.tag }}" + imagePullPolicy: "{{ .Values.pushgateway.image.pullPolicy }}" + args: + {{- range $key, $value := .Values.pushgateway.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + ports: + - containerPort: 9091 + livenessProbe: + httpGet: + {{- if (index .Values "pushgateway" "extraArgs" "web.route-prefix") }} + path: /{{ index .Values "pushgateway" "extraArgs" "web.route-prefix" }}/-/healthy + {{- else }} + path: /-/healthy + {{- end }} + port: 9091 + initialDelaySeconds: 10 + timeoutSeconds: 10 + readinessProbe: + httpGet: + {{- if (index .Values "pushgateway" "extraArgs" "web.route-prefix") }} + path: /{{ index .Values "pushgateway" "extraArgs" "web.route-prefix" }}/-/ready + {{- else }} + path: /-/ready + {{- end }} + port: 9091 + initialDelaySeconds: 10 + timeoutSeconds: 10 + resources: +{{ toYaml .Values.pushgateway.resources | indent 12 }} + {{- if .Values.pushgateway.persistentVolume.enabled }} + volumeMounts: + - name: storage-volume + mountPath: "{{ .Values.pushgateway.persistentVolume.mountPath }}" + subPath: "{{ .Values.pushgateway.persistentVolume.subPath }}" + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{ toYaml .Values.imagePullSecrets | indent 2 }} + {{- end }} + {{- if .Values.pushgateway.nodeSelector }} + nodeSelector: +{{ toYaml .Values.pushgateway.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.securityContext }} + securityContext: +{{ toYaml .Values.pushgateway.securityContext | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.tolerations }} + tolerations: +{{ toYaml .Values.pushgateway.tolerations | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.affinity }} + affinity: +{{ toYaml .Values.pushgateway.affinity | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.persistentVolume.enabled }} + volumes: + - name: storage-volume + persistentVolumeClaim: + claimName: {{ if .Values.pushgateway.persistentVolume.existingClaim }}{{ .Values.pushgateway.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.pushgateway.fullname" . }}{{- end }} + {{- end -}} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-ingress.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-ingress.yaml new file mode 100644 index 00000000000..60c6d7455ee --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-ingress.yaml @@ -0,0 +1,39 @@ +{{- if and .Values.pushgateway.enabled .Values.pushgateway.ingress.enabled -}} +{{- $releaseName := .Release.Name -}} +{{- $serviceName := include "prometheus.pushgateway.fullname" . }} +{{- $servicePort := .Values.pushgateway.service.servicePort -}} +{{- $extraPaths := .Values.pushgateway.ingress.extraPaths -}} +{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +apiVersion: networking.k8s.io/v1beta1 +{{ else }} +apiVersion: extensions/v1beta1 +{{ end -}} +kind: Ingress +metadata: +{{- if .Values.pushgateway.ingress.annotations }} + annotations: +{{ toYaml .Values.pushgateway.ingress.annotations | indent 4}} +{{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +spec: + rules: + {{- range .Values.pushgateway.ingress.hosts }} + {{- $url := splitList "/" . }} + - host: {{ first $url }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: /{{ rest $url | join "/" }} + backend: + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end -}} +{{- if .Values.pushgateway.ingress.tls }} + tls: +{{ toYaml .Values.pushgateway.ingress.tls | indent 4 }} + {{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-networkpolicy.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-networkpolicy.yaml new file mode 100644 index 00000000000..e8f6ab82927 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-networkpolicy.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.pushgateway.enabled .Values.networkPolicy.enabled -}} +apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ template "prometheus.pushgateway.fullname" . }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "prometheus.pushgateway.matchLabels" . | nindent 6 }} + ingress: + - from: + - podSelector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 12 }} + - ports: + - port: 9091 +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-pdb.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-pdb.yaml new file mode 100644 index 00000000000..e9910a5c88b --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-pdb.yaml @@ -0,0 +1,13 @@ +{{- if .Values.pushgateway.podDisruptionBudget.enabled }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "prometheus.pushgateway.fullname" . }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} +spec: + maxUnavailable: {{ .Values.pushgateway.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + {{- include "prometheus.pushgateway.labels" . | nindent 6 }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-podsecuritypolicy.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-podsecuritypolicy.yaml new file mode 100644 index 00000000000..dd3829df295 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-podsecuritypolicy.yaml @@ -0,0 +1,44 @@ +{{- if .Values.rbac.create }} +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "prometheus.pushgateway.fullname" . }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + annotations: +{{- if .Values.pushgateway.podSecurityPolicy.annotations }} +{{ toYaml .Values.pushgateway.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'persistentVolumeClaim' + - 'secret' + allowedHostPaths: + - pathPrefix: {{ .Values.pushgateway.persistentVolume.mountPath }} + hostNetwork: false + hostPID: false + hostIPC: 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: true +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-pvc.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-pvc.yaml new file mode 100644 index 00000000000..ba16a37af23 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-pvc.yaml @@ -0,0 +1,30 @@ +{{- if .Values.pushgateway.persistentVolume.enabled -}} +{{- if not .Values.pushgateway.persistentVolume.existingClaim -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + {{- if .Values.pushgateway.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.pushgateway.persistentVolume.annotations | indent 4 }} + {{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +spec: + accessModes: +{{ toYaml .Values.pushgateway.persistentVolume.accessModes | indent 4 }} +{{- if .Values.pushgateway.persistentVolume.storageClass }} +{{- if (eq "-" .Values.pushgateway.persistentVolume.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.pushgateway.persistentVolume.storageClass }}" +{{- end }} +{{- end }} +{{- if .Values.pushgateway.persistentVolume.volumeBindingMode }} + volumeBindingModeName: "{{ .Values.pushgateway.persistentVolume.volumeBindingMode }}" +{{- end }} + resources: + requests: + storage: "{{ .Values.pushgateway.persistentVolume.size }}" +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-service.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-service.yaml new file mode 100644 index 00000000000..e84771d8bb4 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-service.yaml @@ -0,0 +1,40 @@ +{{- if .Values.pushgateway.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.pushgateway.service.annotations }} + annotations: +{{ toYaml .Values.pushgateway.service.annotations | indent 4}} +{{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} +{{- if .Values.pushgateway.service.labels }} +{{ toYaml .Values.pushgateway.service.labels | indent 4}} +{{- end }} + name: {{ template "prometheus.pushgateway.fullname" . }} +spec: +{{- if .Values.pushgateway.service.clusterIP }} + clusterIP: {{ .Values.pushgateway.service.clusterIP }} +{{- end }} +{{- if .Values.pushgateway.service.externalIPs }} + externalIPs: +{{ toYaml .Values.pushgateway.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.pushgateway.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.pushgateway.service.loadBalancerIP }} +{{- end }} +{{- if .Values.pushgateway.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.pushgateway.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: http + port: {{ .Values.pushgateway.service.servicePort }} + protocol: TCP + targetPort: 9091 + selector: + {{- include "prometheus.pushgateway.matchLabels" . | nindent 4 }} + type: "{{ .Values.pushgateway.service.type }}" +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-serviceaccount.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-serviceaccount.yaml new file mode 100644 index 00000000000..1596a28f9c7 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/pushgateway-serviceaccount.yaml @@ -0,0 +1,8 @@ +{{- if and .Values.pushgateway.enabled .Values.serviceAccounts.pushgateway.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.serviceAccountName.pushgateway" . }} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-clusterrole.yaml b/infra/charts/feast/charts/prometheus/templates/server-clusterrole.yaml new file mode 100644 index 00000000000..c0c0585b9ce --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-clusterrole.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.server.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +rules: +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: + - extensions + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "prometheus.server.fullname" . }} +{{- end }} + - apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + - ingresses + - configmaps + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - ingresses/status + - ingresses + verbs: + - get + - list + - watch + - nonResourceURLs: + - "/metrics" + verbs: + - get +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-clusterrolebinding.yaml b/infra/charts/feast/charts/prometheus/templates/server-clusterrolebinding.yaml new file mode 100644 index 00000000000..1196ce3f2d1 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.server.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.server" . }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "prometheus.server.fullname" . }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-configmap.yaml b/infra/charts/feast/charts/prometheus/templates/server-configmap.yaml new file mode 100644 index 00000000000..ac79fdf2fb6 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-configmap.yaml @@ -0,0 +1,81 @@ +{{- if .Values.server.enabled -}} +{{- if (empty .Values.server.configMapOverrideName) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +data: +{{- $root := . -}} +{{- range $key, $value := .Values.serverFiles }} + {{ $key }}: | +{{- if eq $key "prometheus.yml" }} + global: +{{ $root.Values.server.global | toYaml | trimSuffix "\n" | indent 6 }} +{{- if $root.Values.server.remoteWrite }} + remote_write: +{{ $root.Values.server.remoteWrite | toYaml | indent 4 }} +{{- end }} +{{- if $root.Values.server.remoteRead }} + remote_read: +{{ $root.Values.server.remoteRead | toYaml | indent 4 }} +{{- end }} +{{- end }} +{{- if eq $key "alerts" }} +{{- if and (not (empty $value)) (empty $value.groups) }} + groups: +{{- range $ruleKey, $ruleValue := $value }} + - name: {{ $ruleKey -}}.rules + rules: +{{ $ruleValue | toYaml | trimSuffix "\n" | indent 6 }} +{{- end }} +{{- else }} +{{ toYaml $value | indent 4 }} +{{- end }} +{{- else }} +{{ toYaml $value | default "{}" | indent 4 }} +{{- end }} +{{- if eq $key "prometheus.yml" -}} +{{- if $root.Values.extraScrapeConfigs }} +{{ tpl $root.Values.extraScrapeConfigs $root | indent 4 }} +{{- end -}} +{{- if or ($root.Values.alertmanager.enabled) ($root.Values.server.alertmanagers) }} + alerting: +{{- if $root.Values.alertRelabelConfigs }} +{{ $root.Values.alertRelabelConfigs | toYaml | trimSuffix "\n" | indent 6 }} +{{- end }} + alertmanagers: +{{- if $root.Values.server.alertmanagers }} +{{ toYaml $root.Values.server.alertmanagers | indent 8 }} +{{- else }} + - kubernetes_sd_configs: + - role: pod + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if $root.Values.alertmanager.prefixURL }} + path_prefix: {{ $root.Values.alertmanager.prefixURL }} + {{- end }} + relabel_configs: + - source_labels: [__meta_kubernetes_namespace] + regex: {{ $root.Release.Namespace }} + action: keep + - source_labels: [__meta_kubernetes_pod_label_app] + regex: {{ template "prometheus.name" $root }} + action: keep + - source_labels: [__meta_kubernetes_pod_label_component] + regex: alertmanager + action: keep + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_probe] + regex: {{ index $root.Values.alertmanager.podAnnotations "prometheus.io/probe" | default ".*" }} + action: keep + - source_labels: [__meta_kubernetes_pod_container_port_number] + regex: + action: drop +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-deployment.yaml b/infra/charts/feast/charts/prometheus/templates/server-deployment.yaml new file mode 100644 index 00000000000..79746a238e6 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-deployment.yaml @@ -0,0 +1,217 @@ +{{- if .Values.server.enabled -}} +{{- if not .Values.server.statefulSet.enabled -}} +apiVersion: {{ template "prometheus.deployment.apiVersion" . }} +kind: Deployment +metadata: +{{- if .Values.server.deploymentAnnotations }} + annotations: +{{ toYaml .Values.server.deploymentAnnotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +spec: + selector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 6 }} + replicas: {{ .Values.server.replicaCount }} + {{- if .Values.server.strategy }} + strategy: +{{ toYaml .Values.server.strategy | indent 4 }} + {{- if eq .Values.server.strategy.type "Recreate" }} + rollingUpdate: null + {{- end }} + {{- end }} + template: + metadata: + {{- if .Values.server.podAnnotations }} + annotations: +{{ toYaml .Values.server.podAnnotations | indent 8 }} + {{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 8 }} + {{- if .Values.server.podLabels}} + {{ toYaml .Values.server.podLabels | nindent 8 }} + {{- end}} + spec: +{{- if .Values.server.priorityClassName }} + priorityClassName: "{{ .Values.server.priorityClassName }}" +{{- end }} +{{- if .Values.server.schedulerName }} + schedulerName: "{{ .Values.server.schedulerName }}" +{{- end }} + serviceAccountName: {{ template "prometheus.serviceAccountName.server" . }} + {{- if .Values.server.extraInitContainers }} + initContainers: +{{ toYaml .Values.server.extraInitContainers | indent 8 }} + {{- end }} + containers: + {{- if .Values.configmapReload.prometheus.enabled }} + - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }}-{{ .Values.configmapReload.prometheus.name }} + image: "{{ .Values.configmapReload.prometheus.image.repository }}:{{ .Values.configmapReload.prometheus.image.tag }}" + imagePullPolicy: "{{ .Values.configmapReload.prometheus.image.pullPolicy }}" + args: + - --volume-dir=/etc/config + - --webhook-url=http://127.0.0.1:9090{{ .Values.server.prefixURL }}/-/reload + {{- range $key, $value := .Values.configmapReload.prometheus.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraVolumeDirs }} + - --volume-dir={{ . }} + {{- end }} + resources: +{{ toYaml .Values.configmapReload.prometheus.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- end }} + + - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }} + image: "{{ .Values.server.image.repository }}:{{ .Values.server.image.tag }}" + imagePullPolicy: "{{ .Values.server.image.pullPolicy }}" + {{- if .Values.server.env }} + env: +{{ toYaml .Values.server.env | indent 12}} + {{- end }} + args: + {{- if .Values.server.retention }} + - --storage.tsdb.retention.time={{ .Values.server.retention }} + {{- end }} + - --config.file={{ .Values.server.configPath }} + - --storage.tsdb.path={{ .Values.server.persistentVolume.mountPath }} + - --web.console.libraries=/etc/prometheus/console_libraries + - --web.console.templates=/etc/prometheus/consoles + {{- range .Values.server.extraFlags }} + - --{{ . }} + {{- end }} + {{- if .Values.server.baseURL }} + - --web.external-url={{ .Values.server.baseURL }} + {{- end }} + + {{- range $key, $value := .Values.server.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + ports: + - containerPort: 9090 + readinessProbe: + httpGet: + path: {{ .Values.server.prefixURL }}/-/ready + port: 9090 + initialDelaySeconds: {{ .Values.server.readinessProbeInitialDelay }} + timeoutSeconds: {{ .Values.server.readinessProbeTimeout }} + failureThreshold: {{ .Values.server.readinessProbeFailureThreshold }} + successThreshold: {{ .Values.server.readinessProbeSuccessThreshold }} + livenessProbe: + httpGet: + path: {{ .Values.server.prefixURL }}/-/healthy + port: 9090 + initialDelaySeconds: {{ .Values.server.livenessProbeInitialDelay }} + timeoutSeconds: {{ .Values.server.livenessProbeTimeout }} + failureThreshold: {{ .Values.server.livenessProbeFailureThreshold }} + successThreshold: {{ .Values.server.livenessProbeSuccessThreshold }} + resources: +{{ toYaml .Values.server.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: {{ .Values.server.persistentVolume.mountPath }} + subPath: "{{ .Values.server.persistentVolume.subPath }}" + {{- range .Values.server.extraHostPathMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.server.extraConfigmapMounts }} + - name: {{ $.Values.server.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.server.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- if .Values.server.extraVolumeMounts }} + {{ toYaml .Values.server.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.server.sidecarContainers }} + {{- toYaml .Values.server.sidecarContainers | nindent 8 }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{ toYaml .Values.imagePullSecrets | indent 2 }} + {{- end }} + {{- if .Values.server.nodeSelector }} + nodeSelector: +{{ toYaml .Values.server.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.server.securityContext }} + securityContext: +{{ toYaml .Values.server.securityContext | indent 8 }} + {{- end }} + {{- if .Values.server.tolerations }} + tolerations: +{{ toYaml .Values.server.tolerations | indent 8 }} + {{- end }} + {{- if .Values.server.affinity }} + affinity: +{{ toYaml .Values.server.affinity | indent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.server.terminationGracePeriodSeconds }} + volumes: + - name: config-volume + configMap: + name: {{ if .Values.server.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.server.configMapOverrideName }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} + - name: storage-volume + {{- if .Values.server.persistentVolume.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.server.persistentVolume.existingClaim }}{{ .Values.server.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} + {{- else }} + emptyDir: + {{- if .Values.server.emptyDir.sizeLimit }} + sizeLimit: {{ .Values.server.emptyDir.sizeLimit }} + {{- else }} + {} + {{- end -}} + {{- end -}} +{{- if .Values.server.extraVolumes }} +{{ toYaml .Values.server.extraVolumes | indent 8}} +{{- end }} + {{- range .Values.server.extraHostPathMounts }} + - name: {{ .name }} + hostPath: + path: {{ .hostPath }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.server.extraConfigmapMounts }} + - name: {{ $.Values.server.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.server.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-ingress.yaml b/infra/charts/feast/charts/prometheus/templates/server-ingress.yaml new file mode 100644 index 00000000000..16f0a2af748 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-ingress.yaml @@ -0,0 +1,44 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.server.ingress.enabled -}} +{{- $releaseName := .Release.Name -}} +{{- $serviceName := include "prometheus.server.fullname" . }} +{{- $servicePort := .Values.server.service.servicePort -}} +{{- $extraPaths := .Values.server.ingress.extraPaths -}} +{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +apiVersion: networking.k8s.io/v1beta1 +{{ else }} +apiVersion: extensions/v1beta1 +{{ end -}} +kind: Ingress +metadata: +{{- if .Values.server.ingress.annotations }} + annotations: +{{ toYaml .Values.server.ingress.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +{{- range $key, $value := .Values.server.ingress.extraLabels }} + {{ $key }}: {{ $value }} +{{- end }} + name: {{ template "prometheus.server.fullname" . }} +spec: + rules: + {{- range .Values.server.ingress.hosts }} + {{- $url := splitList "/" . }} + - host: {{ first $url }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: /{{ rest $url | join "/" }} + backend: + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end -}} +{{- if .Values.server.ingress.tls }} + tls: +{{ toYaml .Values.server.ingress.tls | indent 4 }} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-networkpolicy.yaml b/infra/charts/feast/charts/prometheus/templates/server-networkpolicy.yaml new file mode 100644 index 00000000000..9e10129deb5 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-networkpolicy.yaml @@ -0,0 +1,17 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.networkPolicy.enabled }} +apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ template "prometheus.server.fullname" . }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 6 }} + ingress: + - ports: + - port: 9090 +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-pdb.yaml b/infra/charts/feast/charts/prometheus/templates/server-pdb.yaml new file mode 100644 index 00000000000..b2447fdba2b --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-pdb.yaml @@ -0,0 +1,13 @@ +{{- if .Values.server.podDisruptionBudget.enabled }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "prometheus.server.fullname" . }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +spec: + maxUnavailable: {{ .Values.server.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + {{- include "prometheus.server.labels" . | nindent 6 }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-podsecuritypolicy.yaml b/infra/charts/feast/charts/prometheus/templates/server-podsecuritypolicy.yaml new file mode 100644 index 00000000000..a0e15a348d2 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-podsecuritypolicy.yaml @@ -0,0 +1,53 @@ +{{- if .Values.rbac.create }} +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "prometheus.server.fullname" . }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + annotations: +{{- if .Values.server.podSecurityPolicy.annotations }} +{{ toYaml .Values.server.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: + - 'CHOWN' + volumes: + - 'configMap' + - 'persistentVolumeClaim' + - 'emptyDir' + - 'secret' + - 'hostPath' + allowedHostPaths: + - pathPrefix: /etc + readOnly: true + - pathPrefix: {{ .Values.server.persistentVolume.mountPath }} + {{- range .Values.server.extraHostPathMounts }} + - pathPrefix: {{ .hostPath }} + readOnly: {{ .readOnly }} + {{- end }} + hostNetwork: false + hostPID: false + hostIPC: 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 }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-pvc.yaml b/infra/charts/feast/charts/prometheus/templates/server-pvc.yaml new file mode 100644 index 00000000000..9d1cb371bfd --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-pvc.yaml @@ -0,0 +1,34 @@ +{{- if .Values.server.enabled -}} +{{- if not .Values.server.statefulSet.enabled -}} +{{- if .Values.server.persistentVolume.enabled -}} +{{- if not .Values.server.persistentVolume.existingClaim -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + {{- if .Values.server.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.server.persistentVolume.annotations | indent 4 }} + {{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +spec: + accessModes: +{{ toYaml .Values.server.persistentVolume.accessModes | indent 4 }} +{{- if .Values.server.persistentVolume.storageClass }} +{{- if (eq "-" .Values.server.persistentVolume.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.server.persistentVolume.storageClass }}" +{{- end }} +{{- end }} +{{- if .Values.server.persistentVolume.volumeBindingMode }} + volumeBindingModeName: "{{ .Values.server.persistentVolume.volumeBindingMode }}" +{{- end }} + resources: + requests: + storage: "{{ .Values.server.persistentVolume.size }}" +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-service-headless.yaml b/infra/charts/feast/charts/prometheus/templates/server-service-headless.yaml new file mode 100644 index 00000000000..3edc58c00f4 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-service-headless.yaml @@ -0,0 +1,26 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.server.statefulSet.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.server.statefulSet.headless.annotations }} + annotations: +{{ toYaml .Values.server.statefulSet.headless.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +{{- if .Values.server.statefulSet.headless.labels }} +{{ toYaml .Values.server.statefulSet.headless.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.server.fullname" . }}-headless +spec: + clusterIP: None + ports: + - name: http + port: {{ .Values.server.statefulSet.headless.servicePort }} + protocol: TCP + targetPort: 9090 + selector: + {{- include "prometheus.server.matchLabels" . | nindent 4 }} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-service.yaml b/infra/charts/feast/charts/prometheus/templates/server-service.yaml new file mode 100644 index 00000000000..1f06151c038 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-service.yaml @@ -0,0 +1,59 @@ +{{- if .Values.server.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.server.service.annotations }} + annotations: +{{ toYaml .Values.server.service.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +{{- if .Values.server.service.labels }} +{{ toYaml .Values.server.service.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.server.fullname" . }} +spec: +{{- if .Values.server.service.clusterIP }} + clusterIP: {{ .Values.server.service.clusterIP }} +{{- end }} +{{- if .Values.server.service.externalIPs }} + externalIPs: +{{ toYaml .Values.server.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.server.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.server.service.loadBalancerIP }} +{{- end }} +{{- if .Values.server.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.server.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: http + port: {{ .Values.server.service.servicePort }} + protocol: TCP + targetPort: 9090 + {{- if .Values.server.service.nodePort }} + nodePort: {{ .Values.server.service.nodePort }} + {{- end }} + {{- if .Values.server.service.gRPC.enabled }} + - name: grpc + port: {{ .Values.server.service.gRPC.servicePort }} + protocol: TCP + targetPort: 10901 + {{- if .Values.server.service.gRPC.nodePort }} + nodePort: {{ .Values.server.service.gRPC.nodePort }} + {{- end }} + {{- end }} + selector: + {{- if and .Values.server.statefulSet.enabled .Values.server.service.statefulsetReplica.enabled }} + statefulset.kubernetes.io/pod-name: {{ .Release.Name }}-{{ .Values.server.name }}-{{ .Values.server.service.statefulsetReplica.replica }} + {{- else -}} + {{- include "prometheus.server.matchLabels" . | nindent 4 }} +{{- if .Values.server.service.sessionAffinity }} + sessionAffinity: {{ .Values.server.service.sessionAffinity }} +{{- end }} + {{- end }} + type: "{{ .Values.server.service.type }}" +{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-serviceaccount.yaml b/infra/charts/feast/charts/prometheus/templates/server-serviceaccount.yaml new file mode 100644 index 00000000000..68c64121aae --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-serviceaccount.yaml @@ -0,0 +1,10 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.serviceAccounts.server.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.serviceAccountName.server" . }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-statefulset.yaml b/infra/charts/feast/charts/prometheus/templates/server-statefulset.yaml new file mode 100644 index 00000000000..ea6ae550f41 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-statefulset.yaml @@ -0,0 +1,222 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.server.statefulSet.enabled -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: +{{- if .Values.server.statefulSet.annotations }} + annotations: +{{ toYaml .Values.server.statefulSet.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + {{- if .Values.server.statefulSet.labels}} + {{ toYaml .Values.server.statefulSet.labels | nindent 4 }} + {{- end}} + name: {{ template "prometheus.server.fullname" . }} +spec: + serviceName: {{ template "prometheus.server.fullname" . }}-headless + selector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 6 }} + replicas: {{ .Values.server.replicaCount }} + podManagementPolicy: {{ .Values.server.statefulSet.podManagementPolicy }} + template: + metadata: + {{- if .Values.server.podAnnotations }} + annotations: +{{ toYaml .Values.server.podAnnotations | indent 8 }} + {{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 8 }} + {{- if .Values.server.statefulSet.labels}} + {{ toYaml .Values.server.statefulSet.labels | nindent 8 }} + {{- end}} + spec: +{{- if .Values.server.affinity }} + affinity: +{{ toYaml .Values.server.affinity | indent 8 }} +{{- end }} +{{- if .Values.server.priorityClassName }} + priorityClassName: "{{ .Values.server.priorityClassName }}" +{{- end }} +{{- if .Values.server.schedulerName }} + schedulerName: "{{ .Values.server.schedulerName }}" +{{- end }} + serviceAccountName: {{ template "prometheus.serviceAccountName.server" . }} + containers: + {{- if .Values.configmapReload.prometheus.enabled }} + - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }}-{{ .Values.configmapReload.prometheus.name }} + image: "{{ .Values.configmapReload.prometheus.image.repository }}:{{ .Values.configmapReload.prometheus.image.tag }}" + imagePullPolicy: "{{ .Values.configmapReload.prometheus.image.pullPolicy }}" + args: + - --volume-dir=/etc/config + - --webhook-url=http://127.0.0.1:9090{{ .Values.server.prefixURL }}/-/reload + {{- range $key, $value := .Values.configmapReload.prometheus.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraVolumeDirs }} + - --volume-dir={{ . }} + {{- end }} + resources: +{{ toYaml .Values.configmapReload.prometheus.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- end }} + - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }} + image: "{{ .Values.server.image.repository }}:{{ .Values.server.image.tag }}" + imagePullPolicy: "{{ .Values.server.image.pullPolicy }}" + {{- if .Values.server.env }} + env: +{{ toYaml .Values.server.env | indent 12}} + {{- end }} + args: + {{- if .Values.server.retention }} + - --storage.tsdb.retention.time={{ .Values.server.retention }} + {{- end }} + - --config.file={{ .Values.server.configPath }} + - --storage.tsdb.path={{ .Values.server.persistentVolume.mountPath }} + - --web.console.libraries=/etc/prometheus/console_libraries + - --web.console.templates=/etc/prometheus/consoles + {{- range .Values.server.extraFlags }} + - --{{ . }} + {{- end }} + {{- range $key, $value := .Values.server.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- if .Values.server.baseURL }} + - --web.external-url={{ .Values.server.baseURL }} + {{- end }} + ports: + - containerPort: 9090 + readinessProbe: + httpGet: + path: {{ .Values.server.prefixURL }}/-/ready + port: 9090 + initialDelaySeconds: {{ .Values.server.readinessProbeInitialDelay }} + timeoutSeconds: {{ .Values.server.readinessProbeTimeout }} + livenessProbe: + httpGet: + path: {{ .Values.server.prefixURL }}/-/healthy + port: 9090 + initialDelaySeconds: {{ .Values.server.livenessProbeInitialDelay }} + timeoutSeconds: {{ .Values.server.livenessProbeTimeout }} + resources: +{{ toYaml .Values.server.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: {{ .Values.server.persistentVolume.mountPath }} + subPath: "{{ .Values.server.persistentVolume.subPath }}" + {{- range .Values.server.extraHostPathMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.server.extraConfigmapMounts }} + - name: {{ $.Values.server.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.server.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- if .Values.server.extraVolumeMounts }} + {{ toYaml .Values.server.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.server.sidecarContainers }} + {{- toYaml .Values.server.sidecarContainers | nindent 8 }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{ toYaml .Values.imagePullSecrets | indent 2 }} + {{- end }} + {{- if .Values.server.nodeSelector }} + nodeSelector: +{{ toYaml .Values.server.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.server.securityContext }} + securityContext: +{{ toYaml .Values.server.securityContext | indent 8 }} + {{- end }} + {{- if .Values.server.tolerations }} + tolerations: +{{ toYaml .Values.server.tolerations | indent 8 }} + {{- end }} + {{- if .Values.server.affinity }} + affinity: +{{ toYaml .Values.server.affinity | indent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.server.terminationGracePeriodSeconds }} + volumes: + - name: config-volume + configMap: + name: {{ if .Values.server.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.server.configMapOverrideName }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} + {{- range .Values.server.extraHostPathMounts }} + - name: {{ .name }} + hostPath: + path: {{ .hostPath }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.server.extraConfigmapMounts }} + - name: {{ $.Values.server.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.server.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} +{{- if .Values.server.extraVolumes }} +{{ toYaml .Values.server.extraVolumes | indent 8}} +{{- end }} +{{- if .Values.server.persistentVolume.enabled }} + volumeClaimTemplates: + - metadata: + name: storage-volume + {{- if .Values.server.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.server.persistentVolume.annotations | indent 10 }} + {{- end }} + spec: + accessModes: +{{ toYaml .Values.server.persistentVolume.accessModes | indent 10 }} + resources: + requests: + storage: "{{ .Values.server.persistentVolume.size }}" + {{- if .Values.server.persistentVolume.storageClass }} + {{- if (eq "-" .Values.server.persistentVolume.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.server.persistentVolume.storageClass }}" + {{- end }} + {{- end }} +{{- else }} + - name: storage-volume + emptyDir: {} +{{- end }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-vpa.yaml b/infra/charts/feast/charts/prometheus/templates/server-vpa.yaml new file mode 100644 index 00000000000..ef3604eb0e0 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/templates/server-vpa.yaml @@ -0,0 +1,24 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.server.verticalAutoscaler.enabled -}} +apiVersion: autoscaling.k8s.io/v1beta2 +kind: VerticalPodAutoscaler +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }}-vpa +spec: + targetRef: +{{- if .Values.server.statefulSet.enabled }} + apiVersion: "apps/v1" + kind: StatefulSet +{{- else }} + apiVersion: "extensions/v1beta1" + kind: Deployment +{{- end }} + name: {{ template "prometheus.server.fullname" . }} + updatePolicy: + updateMode: {{ .Values.server.verticalAutoscaler.updateMode | default "Off" | quote }} + resourcePolicy: + containerPolicies: {{ .Values.server.verticalAutoscaler.containerPolicies | default list | toYaml | trim | nindent 4 }} +{{- end -}} {{/* if .Values.server.verticalAutoscaler.enabled */}} +{{- end -}} {{/* .Values.server.enabled */}} diff --git a/infra/charts/feast/charts/prometheus/values.yaml b/infra/charts/feast/charts/prometheus/values.yaml new file mode 100644 index 00000000000..3fee953d963 --- /dev/null +++ b/infra/charts/feast/charts/prometheus/values.yaml @@ -0,0 +1,1514 @@ +rbac: + create: true + +podSecurityPolicy: + enabled: false + +imagePullSecrets: +# - name: "image-pull-secret" + +## Define serviceAccount names for components. Defaults to component's fully qualified name. +## +serviceAccounts: + alertmanager: + create: true + name: + nodeExporter: + create: true + name: + pushgateway: + create: true + name: + server: + create: true + name: + +alertmanager: + ## If false, alertmanager will not be installed + ## + enabled: true + + ## alertmanager container name + ## + name: alertmanager + + ## alertmanager container image + ## + image: + repository: prom/alertmanager + tag: v0.20.0 + pullPolicy: IfNotPresent + + ## alertmanager priorityClassName + ## + priorityClassName: "" + + ## Additional alertmanager container arguments + ## + extraArgs: {} + + ## The URL prefix at which the container can be accessed. Useful in the case the '-web.external-url' includes a slug + ## so that the various internal URLs are still able to access as they are in the default case. + ## (Optional) + prefixURL: "" + + ## External URL which can access alertmanager + baseURL: "http://localhost:9093" + + ## Additional alertmanager container environment variable + ## For instance to add a http_proxy + ## + extraEnv: {} + + ## Additional alertmanager Secret mounts + # Defines additional mounts with secrets. Secrets must be manually created in the namespace. + extraSecretMounts: [] + # - name: secret-files + # mountPath: /etc/secrets + # subPath: "" + # secretName: alertmanager-secret-files + # readOnly: true + + ## ConfigMap override where fullname is {{.Release.Name}}-{{.Values.alertmanager.configMapOverrideName}} + ## Defining configMapOverrideName will cause templates/alertmanager-configmap.yaml + ## to NOT generate a ConfigMap resource + ## + configMapOverrideName: "" + + ## The name of a secret in the same kubernetes namespace which contains the Alertmanager config + ## Defining configFromSecret will cause templates/alertmanager-configmap.yaml + ## to NOT generate a ConfigMap resource + ## + configFromSecret: "" + + ## The configuration file name to be loaded to alertmanager + ## Must match the key within configuration loaded from ConfigMap/Secret + ## + configFileName: alertmanager.yml + + ingress: + ## If true, alertmanager Ingress will be created + ## + enabled: false + + ## alertmanager Ingress annotations + ## + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: 'true' + + ## alertmanager Ingress additional labels + ## + extraLabels: {} + + ## alertmanager Ingress hostnames with optional path + ## Must be provided if Ingress is enabled + ## + hosts: [] + # - alertmanager.domain.com + # - domain.com/alertmanager + + ## 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 + + ## alertmanager Ingress TLS configuration + ## Secrets must be manually created in the namespace + ## + tls: [] + # - secretName: prometheus-alerts-tls + # hosts: + # - alertmanager.domain.com + + ## Alertmanager Deployment Strategy type + # strategy: + # type: Recreate + + ## Node tolerations for alertmanager scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + ## Node labels for alertmanager pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Pod affinity + ## + affinity: {} + + ## PodDisruptionBudget settings + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + ## + podDisruptionBudget: + enabled: false + maxUnavailable: 1 + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + persistentVolume: + ## If true, alertmanager will create/use a Persistent Volume Claim + ## If false, use emptyDir + ## + enabled: true + + ## alertmanager data Persistent Volume access modes + ## Must match those of existing PV or dynamic provisioner + ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + accessModes: + - ReadWriteOnce + + ## alertmanager data Persistent Volume Claim annotations + ## + annotations: {} + + ## alertmanager data Persistent Volume existing claim name + ## Requires alertmanager.persistentVolume.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: "" + + ## alertmanager data Persistent Volume mount root path + ## + mountPath: /data + + ## alertmanager data Persistent Volume size + ## + size: 2Gi + + ## alertmanager data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + + ## alertmanager data Persistent Volume Binding Mode + ## If defined, volumeBindingMode: + ## If undefined (the default) or set to null, no volumeBindingMode spec is + ## set, choosing the default mode. + ## + # volumeBindingMode: "" + + ## Subdirectory of alertmanager data Persistent Volume to mount + ## Useful if the volume's root directory is not empty + ## + subPath: "" + + ## Annotations to be added to alertmanager pods + ## + podAnnotations: {} + ## Tell prometheus to use a specific set of alertmanager pods + ## instead of all alertmanager pods found in the same namespace + ## Useful if you deploy multiple releases within the same namespace + ## + ## prometheus.io/probe: alertmanager-teamA + + ## Labels to be added to Prometheus AlertManager pods + ## + podLabels: {} + + ## Specify if a Pod Security Policy for node-exporter 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' + + ## Use a StatefulSet if replicaCount needs to be greater than 1 (see below) + ## + replicaCount: 1 + + statefulSet: + ## If true, use a statefulset instead of a deployment for pod management. + ## This allows to scale replicas to more than 1 pod + ## + enabled: false + + podManagementPolicy: OrderedReady + + ## Alertmanager headless service to use for the statefulset + ## + headless: + annotations: {} + labels: {} + + ## Enabling peer mesh service end points for enabling the HA alert manager + ## Ref: https://github.com/prometheus/alertmanager/blob/master/README.md + # enableMeshPeer : true + + servicePort: 80 + + ## alertmanager resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + + ## Security context to be added to alertmanager pods + ## + securityContext: + runAsUser: 65534 + runAsNonRoot: true + runAsGroup: 65534 + fsGroup: 65534 + + service: + annotations: {} + labels: {} + clusterIP: "" + + ## Enabling peer mesh service end points for enabling the HA alert manager + ## Ref: https://github.com/prometheus/alertmanager/blob/master/README.md + # enableMeshPeer : true + + ## List of IP addresses at which the alertmanager service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 80 + # nodePort: 30000 + sessionAffinity: None + type: ClusterIP + +## Monitors ConfigMap changes and POSTs to a URL +## Ref: https://github.com/jimmidyson/configmap-reload +## +configmapReload: + prometheus: + ## If false, the configmap-reload container will not be deployed + ## + enabled: true + + ## configmap-reload container name + ## + name: configmap-reload + + ## configmap-reload container image + ## + image: + repository: jimmidyson/configmap-reload + tag: v0.3.0 + pullPolicy: IfNotPresent + + ## Additional configmap-reload container arguments + ## + extraArgs: {} + ## Additional configmap-reload volume directories + ## + extraVolumeDirs: [] + + + ## Additional configmap-reload mounts + ## + extraConfigmapMounts: [] + # - name: prometheus-alerts + # mountPath: /etc/alerts.d + # subPath: "" + # configMap: prometheus-alerts + # readOnly: true + + + ## configmap-reload resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + alertmanager: + ## If false, the configmap-reload container will not be deployed + ## + enabled: true + + ## configmap-reload container name + ## + name: configmap-reload + + ## configmap-reload container image + ## + image: + repository: jimmidyson/configmap-reload + tag: v0.3.0 + pullPolicy: IfNotPresent + + ## Additional configmap-reload container arguments + ## + extraArgs: {} + ## Additional configmap-reload volume directories + ## + extraVolumeDirs: [] + + + ## Additional configmap-reload mounts + ## + extraConfigmapMounts: [] + # - name: prometheus-alerts + # mountPath: /etc/alerts.d + # subPath: "" + # configMap: prometheus-alerts + # readOnly: true + + + ## configmap-reload resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + +kubeStateMetrics: + ## If false, kube-state-metrics sub-chart will not be installed + ## Please see https://github.com/helm/charts/tree/master/stable/kube-state-metrics for configurable values + ## + enabled: true + +nodeExporter: + ## If false, node-exporter will not be installed + ## + enabled: false + + ## If true, node-exporter pods share the host network namespace + ## + hostNetwork: true + + ## If true, node-exporter pods share the host PID namespace + ## + hostPID: true + + ## node-exporter container name + ## + name: node-exporter + + ## node-exporter container image + ## + image: + repository: prom/node-exporter + tag: v0.18.1 + pullPolicy: IfNotPresent + + ## Specify if a Pod Security Policy for node-exporter 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' + + ## node-exporter priorityClassName + ## + priorityClassName: "" + + ## Custom Update Strategy + ## + updateStrategy: + type: RollingUpdate + + ## Additional node-exporter container arguments + ## + extraArgs: {} + + ## Additional node-exporter hostPath mounts + ## + extraHostPathMounts: [] + # - name: textfile-dir + # mountPath: /srv/txt_collector + # hostPath: /var/lib/node-exporter + # readOnly: true + # mountPropagation: HostToContainer + + extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /prometheus + # configMap: certs-configmap + # readOnly: true + + ## Node tolerations for node-exporter scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + ## Node labels for node-exporter pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Annotations to be added to node-exporter pods + ## + podAnnotations: {} + + ## Labels to be added to node-exporter pods + ## + pod: + labels: {} + + ## PodDisruptionBudget settings + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + ## + podDisruptionBudget: + enabled: false + maxUnavailable: 1 + + ## node-exporter resource limits & requests + ## Ref: https://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 200m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 30Mi + + ## Security context to be added to node-exporter pods + ## + securityContext: {} + # runAsUser: 0 + + service: + annotations: + prometheus.io/scrape: "true" + labels: {} + + # Exposed as a headless service: + # https://kubernetes.io/docs/concepts/services-networking/service/#headless-services + clusterIP: None + + ## List of IP addresses at which the node-exporter service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + hostPort: 9100 + loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 9100 + type: ClusterIP + +server: + ## Prometheus server container name + ## + enabled: true + name: server + sidecarContainers: + + ## Prometheus server container image + ## + image: + repository: prom/prometheus + tag: v2.16.0 + pullPolicy: IfNotPresent + + ## prometheus server priorityClassName + ## + priorityClassName: "" + + ## The URL prefix at which the container can be accessed. Useful in the case the '-web.external-url' includes a slug + ## so that the various internal URLs are still able to access as they are in the default case. + ## (Optional) + prefixURL: "" + + ## External URL which can access alertmanager + ## Maybe same with Ingress host name + baseURL: "" + + ## Additional server container environment variables + ## + ## You specify this manually like you would a raw deployment manifest. + ## This means you can bind in environment variables from secrets. + ## + ## e.g. static environment variable: + ## - name: DEMO_GREETING + ## value: "Hello from the environment" + ## + ## e.g. secret environment variable: + ## - name: USERNAME + ## valueFrom: + ## secretKeyRef: + ## name: mysecret + ## key: username + env: [] + + extraFlags: + - web.enable-lifecycle + ## web.enable-admin-api flag controls access to the administrative HTTP API which includes functionality such as + ## deleting time series. This is disabled by default. + # - web.enable-admin-api + ## + ## storage.tsdb.no-lockfile flag controls BD locking + # - storage.tsdb.no-lockfile + ## + ## storage.tsdb.wal-compression flag enables compression of the write-ahead log (WAL) + # - storage.tsdb.wal-compression + + ## Path to a configuration file on prometheus server container FS + configPath: /etc/config/prometheus.yml + + global: + ## How frequently to scrape targets by default + ## + scrape_interval: 1m + ## How long until a scrape request times out + ## + scrape_timeout: 10s + ## How frequently to evaluate rules + ## + evaluation_interval: 1m + ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write + ## + remoteWrite: {} + ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_read + ## + remoteRead: {} + + ## Additional Prometheus server container arguments + ## + extraArgs: {} + + ## Additional InitContainers to initialize the pod + ## + extraInitContainers: [] + + ## Additional Prometheus server Volume mounts + ## + extraVolumeMounts: [] + + ## Additional Prometheus server Volumes + ## + extraVolumes: [] + + ## Additional Prometheus server hostPath mounts + ## + extraHostPathMounts: [] + # - name: certs-dir + # mountPath: /etc/kubernetes/certs + # subPath: "" + # hostPath: /etc/kubernetes/certs + # readOnly: true + + extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /prometheus + # subPath: "" + # configMap: certs-configmap + # readOnly: true + + ## Additional Prometheus server Secret mounts + # Defines additional mounts with secrets. Secrets must be manually created in the namespace. + extraSecretMounts: [] + # - name: secret-files + # mountPath: /etc/secrets + # subPath: "" + # secretName: prom-secret-files + # readOnly: true + + ## ConfigMap override where fullname is {{.Release.Name}}-{{.Values.server.configMapOverrideName}} + ## Defining configMapOverrideName will cause templates/server-configmap.yaml + ## to NOT generate a ConfigMap resource + ## + configMapOverrideName: "" + + ingress: + ## If true, Prometheus server Ingress will be created + ## + enabled: false + + ## Prometheus server Ingress annotations + ## + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: 'true' + + ## Prometheus server Ingress additional labels + ## + extraLabels: {} + + ## Prometheus server Ingress hostnames with optional path + ## Must be provided if Ingress is enabled + ## + hosts: [] + # - prometheus.domain.com + # - domain.com/prometheus + + ## 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 + + ## Prometheus server Ingress TLS configuration + ## Secrets must be manually created in the namespace + ## + tls: [] + # - secretName: prometheus-server-tls + # hosts: + # - prometheus.domain.com + + ## Server Deployment Strategy type + # strategy: + # type: Recreate + + ## Node tolerations for server scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + ## Node labels for Prometheus server pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Pod affinity + ## + affinity: {} + + ## PodDisruptionBudget settings + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + ## + podDisruptionBudget: + enabled: false + maxUnavailable: 1 + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + persistentVolume: + ## If true, Prometheus server will create/use a Persistent Volume Claim + ## If false, use emptyDir + ## + enabled: true + + ## Prometheus server data Persistent Volume access modes + ## Must match those of existing PV or dynamic provisioner + ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + accessModes: + - ReadWriteOnce + + ## Prometheus server data Persistent Volume annotations + ## + annotations: {} + + ## Prometheus server data Persistent Volume existing claim name + ## Requires server.persistentVolume.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: "" + + ## Prometheus server data Persistent Volume mount root path + ## + mountPath: /data + + ## Prometheus server data Persistent Volume size + ## + size: 8Gi + + ## Prometheus server data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + + ## Prometheus server data Persistent Volume Binding Mode + ## If defined, volumeBindingMode: + ## If undefined (the default) or set to null, no volumeBindingMode spec is + ## set, choosing the default mode. + ## + # volumeBindingMode: "" + + ## Subdirectory of Prometheus server data Persistent Volume to mount + ## Useful if the volume's root directory is not empty + ## + subPath: "" + + emptyDir: + sizeLimit: "" + + ## Annotations to be added to Prometheus server pods + ## + podAnnotations: {} + # iam.amazonaws.com/role: prometheus + + ## Labels to be added to Prometheus server pods + ## + podLabels: {} + + ## Prometheus AlertManager configuration + ## + alertmanagers: [] + + ## Specify if a Pod Security Policy for node-exporter 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' + + ## Use a StatefulSet if replicaCount needs to be greater than 1 (see below) + ## + replicaCount: 1 + + statefulSet: + ## If true, use a statefulset instead of a deployment for pod management. + ## This allows to scale replicas to more than 1 pod + ## + enabled: false + + annotations: {} + labels: {} + podManagementPolicy: OrderedReady + + ## Alertmanager headless service to use for the statefulset + ## + headless: + annotations: {} + labels: {} + servicePort: 80 + + ## Prometheus server readiness and liveness probe initial delay and timeout + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ + ## + readinessProbeInitialDelay: 30 + readinessProbeTimeout: 30 + readinessProbeFailureThreshold: 3 + readinessProbeSuccessThreshold: 1 + livenessProbeInitialDelay: 30 + livenessProbeTimeout: 30 + livenessProbeFailureThreshold: 3 + livenessProbeSuccessThreshold: 1 + + ## Prometheus server resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 500m + # memory: 512Mi + # requests: + # cpu: 500m + # memory: 512Mi + + ## Vertical Pod Autoscaler config + ## Ref: https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler + verticalAutoscaler: + ## If true a VPA object will be created for the controller (either StatefulSet or Deployemnt, based on above configs) + enabled: false + # updateMode: "Auto" + # containerPolicies: + # - containerName: 'prometheus-server' + + ## Security context to be added to server pods + ## + securityContext: + runAsUser: 65534 + runAsNonRoot: true + runAsGroup: 65534 + fsGroup: 65534 + + service: + annotations: {} + labels: {} + clusterIP: "" + + ## List of IP addresses at which the Prometheus server service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 80 + sessionAffinity: None + type: ClusterIP + + ## Enable gRPC port on service to allow auto discovery with thanos-querier + gRPC: + enabled: false + servicePort: 10901 + # nodePort: 10901 + + ## If using a statefulSet (statefulSet.enabled=true), configure the + ## service to connect to a specific replica to have a consistent view + ## of the data. + statefulsetReplica: + enabled: false + replica: 0 + + ## Prometheus server pod termination grace period + ## + terminationGracePeriodSeconds: 300 + + ## Prometheus data retention period (default if not specified is 15 days) + ## + retention: "15d" + +pushgateway: + ## If false, pushgateway will not be installed + ## + enabled: true + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## pushgateway container name + ## + name: pushgateway + + ## pushgateway container image + ## + image: + repository: prom/pushgateway + tag: v1.0.1 + pullPolicy: IfNotPresent + + ## pushgateway priorityClassName + ## + priorityClassName: "" + + ## Additional pushgateway container arguments + ## + ## for example: persistence.file: /data/pushgateway.data + extraArgs: {} + + ingress: + ## If true, pushgateway Ingress will be created + ## + enabled: false + + ## pushgateway Ingress annotations + ## + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: 'true' + + ## pushgateway Ingress hostnames with optional path + ## Must be provided if Ingress is enabled + ## + hosts: [] + # - pushgateway.domain.com + # - domain.com/pushgateway + + ## 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 + + ## pushgateway Ingress TLS configuration + ## Secrets must be manually created in the namespace + ## + tls: [] + # - secretName: prometheus-alerts-tls + # hosts: + # - pushgateway.domain.com + + ## Node tolerations for pushgateway scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + ## Node labels for pushgateway pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Annotations to be added to pushgateway pods + ## + podAnnotations: {} + + ## Specify if a Pod Security Policy for node-exporter 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' + + replicaCount: 1 + + ## PodDisruptionBudget settings + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + ## + podDisruptionBudget: + enabled: false + maxUnavailable: 1 + + ## pushgateway resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + + ## Security context to be added to push-gateway pods + ## + securityContext: + runAsUser: 65534 + runAsNonRoot: true + + service: + annotations: + prometheus.io/probe: pushgateway + labels: {} + clusterIP: "" + + ## List of IP addresses at which the pushgateway service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 9091 + type: ClusterIP + + ## pushgateway Deployment Strategy type + # strategy: + # type: Recreate + + persistentVolume: + ## If true, pushgateway will create/use a Persistent Volume Claim + ## If false, use emptyDir + ## + enabled: false + + ## pushgateway data Persistent Volume access modes + ## Must match those of existing PV or dynamic provisioner + ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + accessModes: + - ReadWriteOnce + + ## pushgateway data Persistent Volume Claim annotations + ## + annotations: {} + + ## pushgateway data Persistent Volume existing claim name + ## Requires pushgateway.persistentVolume.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: "" + + ## pushgateway data Persistent Volume mount root path + ## + mountPath: /data + + ## pushgateway data Persistent Volume size + ## + size: 2Gi + + ## pushgateway data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + + ## pushgateway data Persistent Volume Binding Mode + ## If defined, volumeBindingMode: + ## If undefined (the default) or set to null, no volumeBindingMode spec is + ## set, choosing the default mode. + ## + # volumeBindingMode: "" + + ## Subdirectory of pushgateway data Persistent Volume to mount + ## Useful if the volume's root directory is not empty + ## + subPath: "" + + +## alertmanager ConfigMap entries +## +alertmanagerFiles: + alertmanager.yml: + global: {} + # slack_api_url: '' + + receivers: + - name: default-receiver + # slack_configs: + # - channel: '@you' + # send_resolved: true + + route: + group_wait: 10s + group_interval: 5m + receiver: default-receiver + repeat_interval: 3h + +## Prometheus server ConfigMap entries +## +serverFiles: + + ## Alerts configuration + ## Ref: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ + alerting_rules.yml: {} + # groups: + # - name: Instances + # rules: + # - alert: InstanceDown + # expr: up == 0 + # for: 5m + # labels: + # severity: page + # annotations: + # description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes.' + # summary: 'Instance {{ $labels.instance }} down' + ## DEPRECATED DEFAULT VALUE, unless explicitly naming your files, please use alerting_rules.yml + alerts: {} + + ## Records configuration + ## Ref: https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/ + recording_rules.yml: {} + ## DEPRECATED DEFAULT VALUE, unless explicitly naming your files, please use recording_rules.yml + rules: {} + + prometheus.yml: + rule_files: + - /etc/config/recording_rules.yml + - /etc/config/alerting_rules.yml + ## Below two files are DEPRECATED will be removed from this default values file + - /etc/config/rules + - /etc/config/alerts + + scrape_configs: + - job_name: prometheus + static_configs: + - targets: + - localhost:9090 + + # A scrape configuration for running Prometheus on a Kubernetes cluster. + # This uses separate scrape configs for cluster components (i.e. API server, node) + # and services to allow each to use different authentication configs. + # + # Kubernetes labels will be added as Prometheus labels on metrics via the + # `labelmap` relabeling action. + + # Scrape config for API servers. + # + # Kubernetes exposes API servers as endpoints to the default/kubernetes + # service so this uses `endpoints` role and uses relabelling to only keep + # the endpoints associated with the default/kubernetes service using the + # default named port `https`. This works for single API server deployments as + # well as HA API server deployments. + - job_name: 'kubernetes-apiservers' + + kubernetes_sd_configs: + - role: endpoints + + # Default to scraping over https. If required, just disable this or change to + # `http`. + scheme: https + + # This TLS & bearer token file config is used to connect to the actual scrape + # endpoints for cluster components. This is separate to discovery auth + # configuration because discovery & scraping are two separate concerns in + # Prometheus. The discovery auth config is automatic if Prometheus runs inside + # the cluster. Otherwise, more config options have to be provided within the + # . + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + # If your node certificates are self-signed or use a different CA to the + # master CA, then disable certificate verification below. Note that + # certificate verification is an integral part of a secure infrastructure + # so this should only be disabled in a controlled environment. You can + # disable certificate verification by uncommenting the line below. + # + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + # Keep only the default/kubernetes service endpoints for the https port. This + # will add targets for each API server which Kubernetes adds an endpoint to + # the default/kubernetes service. + relabel_configs: + - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] + action: keep + regex: default;kubernetes;https + + - job_name: 'kubernetes-nodes' + + # Default to scraping over https. If required, just disable this or change to + # `http`. + scheme: https + + # This TLS & bearer token file config is used to connect to the actual scrape + # endpoints for cluster components. This is separate to discovery auth + # configuration because discovery & scraping are two separate concerns in + # Prometheus. The discovery auth config is automatic if Prometheus runs inside + # the cluster. Otherwise, more config options have to be provided within the + # . + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + # If your node certificates are self-signed or use a different CA to the + # master CA, then disable certificate verification below. Note that + # certificate verification is an integral part of a secure infrastructure + # so this should only be disabled in a controlled environment. You can + # disable certificate verification by uncommenting the line below. + # + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + kubernetes_sd_configs: + - role: node + + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - target_label: __address__ + replacement: kubernetes.default.svc:443 + - source_labels: [__meta_kubernetes_node_name] + regex: (.+) + target_label: __metrics_path__ + replacement: /api/v1/nodes/$1/proxy/metrics + + + - job_name: 'kubernetes-nodes-cadvisor' + + # Default to scraping over https. If required, just disable this or change to + # `http`. + scheme: https + + # This TLS & bearer token file config is used to connect to the actual scrape + # endpoints for cluster components. This is separate to discovery auth + # configuration because discovery & scraping are two separate concerns in + # Prometheus. The discovery auth config is automatic if Prometheus runs inside + # the cluster. Otherwise, more config options have to be provided within the + # . + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + # If your node certificates are self-signed or use a different CA to the + # master CA, then disable certificate verification below. Note that + # certificate verification is an integral part of a secure infrastructure + # so this should only be disabled in a controlled environment. You can + # disable certificate verification by uncommenting the line below. + # + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + kubernetes_sd_configs: + - role: node + + # This configuration will work only on kubelet 1.7.3+ + # As the scrape endpoints for cAdvisor have changed + # if you are using older version you need to change the replacement to + # replacement: /api/v1/nodes/$1:4194/proxy/metrics + # more info here https://github.com/coreos/prometheus-operator/issues/633 + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - target_label: __address__ + replacement: kubernetes.default.svc:443 + - source_labels: [__meta_kubernetes_node_name] + regex: (.+) + target_label: __metrics_path__ + replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor + + # Scrape config for service endpoints. + # + # The relabeling allows the actual service scrape endpoint to be configured + # via the following annotations: + # + # * `prometheus.io/scrape`: Only scrape services that have a value of `true` + # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need + # to set this to `https` & most likely set the `tls_config` of the scrape config. + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: If the metrics are exposed on a different port to the + # service then set this appropriately. + - job_name: 'kubernetes-service-endpoints' + + kubernetes_sd_configs: + - role: endpoints + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: replace + target_label: __scheme__ + regex: (https?) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_service_name] + action: replace + target_label: kubernetes_name + - source_labels: [__meta_kubernetes_pod_node_name] + action: replace + target_label: kubernetes_node + + # Scrape config for slow service endpoints; same as above, but with a larger + # timeout and a larger interval + # + # The relabeling allows the actual service scrape endpoint to be configured + # via the following annotations: + # + # * `prometheus.io/scrape-slow`: Only scrape services that have a value of `true` + # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need + # to set this to `https` & most likely set the `tls_config` of the scrape config. + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: If the metrics are exposed on a different port to the + # service then set this appropriately. + - job_name: 'kubernetes-service-endpoints-slow' + + scrape_interval: 5m + scrape_timeout: 30s + + kubernetes_sd_configs: + - role: endpoints + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape_slow] + action: keep + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: replace + target_label: __scheme__ + regex: (https?) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_service_name] + action: replace + target_label: kubernetes_name + - source_labels: [__meta_kubernetes_pod_node_name] + action: replace + target_label: kubernetes_node + + - job_name: 'prometheus-pushgateway' + honor_labels: true + + kubernetes_sd_configs: + - role: service + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] + action: keep + regex: pushgateway + + # Example scrape config for probing services via the Blackbox Exporter. + # + # The relabeling allows the actual service scrape endpoint to be configured + # via the following annotations: + # + # * `prometheus.io/probe`: Only probe services that have a value of `true` + - job_name: 'kubernetes-services' + + metrics_path: /probe + params: + module: [http_2xx] + + kubernetes_sd_configs: + - role: service + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] + action: keep + regex: true + - source_labels: [__address__] + target_label: __param_target + - target_label: __address__ + replacement: blackbox + - source_labels: [__param_target] + target_label: instance + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_service_name] + target_label: kubernetes_name + + # Example scrape config for pods + # + # The relabeling allows the actual pod scrape endpoint to be configured via the + # following annotations: + # + # * `prometheus.io/scrape`: Only scrape pods that have a value of `true` + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the default of `9102`. + - job_name: 'kubernetes-pods' + + kubernetes_sd_configs: + - role: pod + + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] + action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: kubernetes_pod_name + + # Example Scrape config for pods which should be scraped slower. An useful example + # would be stackriver-exporter which querys an API on every scrape of the pod + # + # The relabeling allows the actual pod scrape endpoint to be configured via the + # following annotations: + # + # * `prometheus.io/scrape-slow`: Only scrape pods that have a value of `true` + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the default of `9102`. + - job_name: 'kubernetes-pods-slow' + + scrape_interval: 5m + scrape_timeout: 30s + + kubernetes_sd_configs: + - role: pod + + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape_slow] + action: keep + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] + action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: kubernetes_pod_name + +# adds additional scrape configs to prometheus.yml +# must be a string so you have to add a | after extraScrapeConfigs: +# example adds prometheus-blackbox-exporter scrape config +extraScrapeConfigs: + # - job_name: 'prometheus-blackbox-exporter' + # metrics_path: /probe + # params: + # module: [http_2xx] + # static_configs: + # - targets: + # - https://example.com + # relabel_configs: + # - source_labels: [__address__] + # target_label: __param_target + # - source_labels: [__param_target] + # target_label: instance + # - target_label: __address__ + # replacement: prometheus-blackbox-exporter:9115 + +# Adds option to add alert_relabel_configs to avoid duplicate alerts in alertmanager +# useful in H/A prometheus with different external labels but the same alerts +alertRelabelConfigs: + # alert_relabel_configs: + # - source_labels: [dc] + # regex: (.+)\d+ + # target_label: dc + +networkPolicy: + ## Enable creation of NetworkPolicy resources. + ## + enabled: false diff --git a/infra/charts/feast/charts/redis/.helmignore b/infra/charts/feast/charts/redis/.helmignore new file mode 100644 index 00000000000..b2767ae17e9 --- /dev/null +++ b/infra/charts/feast/charts/redis/.helmignore @@ -0,0 +1,3 @@ +.git +# OWNERS file for Kubernetes +OWNERS diff --git a/infra/charts/feast/charts/redis/Chart.yaml b/infra/charts/feast/charts/redis/Chart.yaml new file mode 100644 index 00000000000..7f581f9a9be --- /dev/null +++ b/infra/charts/feast/charts/redis/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +name: redis +version: 10.5.6 +appVersion: 5.0.7 +description: Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. +keywords: +- redis +- keyvalue +- database +home: http://redis.io/ +icon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png +sources: +- https://github.com/bitnami/bitnami-docker-redis +maintainers: +- name: Bitnami + email: containers@bitnami.com +- name: desaintmartin + email: cedric@desaintmartin.fr +engine: gotpl diff --git a/infra/charts/feast/charts/redis/OWNERS b/infra/charts/feast/charts/redis/OWNERS new file mode 100644 index 00000000000..0fb15b4266e --- /dev/null +++ b/infra/charts/feast/charts/redis/OWNERS @@ -0,0 +1,18 @@ +approvers: +- carrodher +- javsalgar +- desaintmartin +- juan131 +- prydonius +- sameersbn +- tompizmor +- miguelaeh +reviewers: +- carrodher +- javsalgar +- desaintmartin +- juan131 +- prydonius +- sameersbn +- tompizmor +- miguelaeh diff --git a/infra/charts/feast/charts/redis/README.md b/infra/charts/feast/charts/redis/README.md new file mode 100644 index 00000000000..8d56e897fd3 --- /dev/null +++ b/infra/charts/feast/charts/redis/README.md @@ -0,0 +1,169 @@ +redis +===== +Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. + +Current chart version is `10.5.6` + +Source code can be found [here](http://redis.io/) + + + +## Chart Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| cluster.enabled | bool | `false` | | +| cluster.slaveCount | int | `1` | | +| clusterDomain | string | `"cluster.local"` | | +| configmap | string | `"# Enable AOF https://redis.io/topics/persistence#append-only-file\nappendonly yes\n# Disable RDB persistence, AOF persistence already enabled.\nsave \"\""` | | +| global.redis | object | `{}` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.registry | string | `"docker.io"` | | +| image.repository | string | `"bitnami/redis"` | | +| image.tag | string | `"5.0.7-debian-10-r32"` | | +| master.affinity | object | `{}` | | +| master.command | string | `"/run.sh"` | | +| master.configmap | string | `nil` | | +| master.disableCommands[0] | string | `"FLUSHDB"` | | +| master.disableCommands[1] | string | `"FLUSHALL"` | | +| master.extraFlags | list | `[]` | | +| master.livenessProbe.enabled | bool | `true` | | +| master.livenessProbe.failureThreshold | int | `5` | | +| master.livenessProbe.initialDelaySeconds | int | `5` | | +| master.livenessProbe.periodSeconds | int | `5` | | +| master.livenessProbe.successThreshold | int | `1` | | +| master.livenessProbe.timeoutSeconds | int | `5` | | +| master.persistence.accessModes[0] | string | `"ReadWriteOnce"` | | +| master.persistence.enabled | bool | `true` | | +| master.persistence.matchExpressions | object | `{}` | | +| master.persistence.matchLabels | object | `{}` | | +| master.persistence.path | string | `"/data"` | | +| master.persistence.size | string | `"8Gi"` | | +| master.persistence.subPath | string | `""` | | +| master.podAnnotations | object | `{}` | | +| master.podLabels | object | `{}` | | +| master.readinessProbe.enabled | bool | `true` | | +| master.readinessProbe.failureThreshold | int | `5` | | +| master.readinessProbe.initialDelaySeconds | int | `5` | | +| master.readinessProbe.periodSeconds | int | `5` | | +| master.readinessProbe.successThreshold | int | `1` | | +| master.readinessProbe.timeoutSeconds | int | `1` | | +| master.service.annotations | object | `{}` | | +| master.service.labels | object | `{}` | | +| master.service.loadBalancerIP | string | `nil` | | +| master.service.port | int | `6379` | | +| master.service.type | string | `"ClusterIP"` | | +| master.statefulset.updateStrategy | string | `"RollingUpdate"` | | +| metrics.enabled | bool | `false` | | +| metrics.image.pullPolicy | string | `"IfNotPresent"` | | +| metrics.image.registry | string | `"docker.io"` | | +| metrics.image.repository | string | `"bitnami/redis-exporter"` | | +| metrics.image.tag | string | `"1.4.0-debian-10-r3"` | | +| metrics.podAnnotations."prometheus.io/port" | string | `"9121"` | | +| metrics.podAnnotations."prometheus.io/scrape" | string | `"true"` | | +| metrics.prometheusRule.additionalLabels | object | `{}` | | +| metrics.prometheusRule.enabled | bool | `false` | | +| metrics.prometheusRule.namespace | string | `""` | | +| metrics.prometheusRule.rules | list | `[]` | | +| metrics.service.annotations | object | `{}` | | +| metrics.service.labels | object | `{}` | | +| metrics.service.type | string | `"ClusterIP"` | | +| metrics.serviceMonitor.enabled | bool | `false` | | +| metrics.serviceMonitor.selector.prometheus | string | `"kube-prometheus"` | | +| networkPolicy.enabled | bool | `false` | | +| networkPolicy.ingressNSMatchLabels | object | `{}` | | +| networkPolicy.ingressNSPodMatchLabels | object | `{}` | | +| password | string | `""` | | +| persistence | object | `{}` | | +| podSecurityPolicy.create | bool | `false` | | +| rbac.create | bool | `false` | | +| rbac.role.rules | list | `[]` | | +| redisPort | int | `6379` | | +| securityContext.enabled | bool | `true` | | +| securityContext.fsGroup | int | `1001` | | +| securityContext.runAsUser | int | `1001` | | +| sentinel.configmap | string | `nil` | | +| sentinel.downAfterMilliseconds | int | `60000` | | +| sentinel.enabled | bool | `false` | | +| sentinel.failoverTimeout | int | `18000` | | +| sentinel.image.pullPolicy | string | `"IfNotPresent"` | | +| sentinel.image.registry | string | `"docker.io"` | | +| sentinel.image.repository | string | `"bitnami/redis-sentinel"` | | +| sentinel.image.tag | string | `"5.0.7-debian-10-r27"` | | +| sentinel.initialCheckTimeout | int | `5` | | +| sentinel.livenessProbe.enabled | bool | `true` | | +| sentinel.livenessProbe.failureThreshold | int | `5` | | +| sentinel.livenessProbe.initialDelaySeconds | int | `5` | | +| sentinel.livenessProbe.periodSeconds | int | `5` | | +| sentinel.livenessProbe.successThreshold | int | `1` | | +| sentinel.livenessProbe.timeoutSeconds | int | `5` | | +| sentinel.masterSet | string | `"mymaster"` | | +| sentinel.parallelSyncs | int | `1` | | +| sentinel.port | int | `26379` | | +| sentinel.quorum | int | `2` | | +| sentinel.readinessProbe.enabled | bool | `true` | | +| sentinel.readinessProbe.failureThreshold | int | `5` | | +| sentinel.readinessProbe.initialDelaySeconds | int | `5` | | +| sentinel.readinessProbe.periodSeconds | int | `5` | | +| sentinel.readinessProbe.successThreshold | int | `1` | | +| sentinel.readinessProbe.timeoutSeconds | int | `1` | | +| sentinel.service.annotations | object | `{}` | | +| sentinel.service.labels | object | `{}` | | +| sentinel.service.loadBalancerIP | string | `nil` | | +| sentinel.service.redisPort | int | `6379` | | +| sentinel.service.sentinelPort | int | `26379` | | +| sentinel.service.type | string | `"ClusterIP"` | | +| sentinel.staticID | bool | `false` | | +| sentinel.usePassword | bool | `true` | | +| serviceAccount.create | bool | `false` | | +| serviceAccount.name | string | `nil` | | +| slave.affinity | object | `{}` | | +| slave.command | string | `"/run.sh"` | | +| slave.configmap | string | `nil` | | +| slave.disableCommands[0] | string | `"FLUSHDB"` | | +| slave.disableCommands[1] | string | `"FLUSHALL"` | | +| slave.extraFlags | list | `[]` | | +| slave.livenessProbe.enabled | bool | `true` | | +| slave.livenessProbe.failureThreshold | int | `5` | | +| slave.livenessProbe.initialDelaySeconds | int | `30` | | +| slave.livenessProbe.periodSeconds | int | `10` | | +| slave.livenessProbe.successThreshold | int | `1` | | +| slave.livenessProbe.timeoutSeconds | int | `5` | | +| slave.persistence.accessModes[0] | string | `"ReadWriteOnce"` | | +| slave.persistence.enabled | bool | `true` | | +| slave.persistence.matchExpressions | object | `{}` | | +| slave.persistence.matchLabels | object | `{}` | | +| slave.persistence.path | string | `"/data"` | | +| slave.persistence.size | string | `"8Gi"` | | +| slave.persistence.subPath | string | `""` | | +| slave.podAnnotations | object | `{}` | | +| slave.podLabels | object | `{}` | | +| slave.port | int | `6379` | | +| slave.readinessProbe.enabled | bool | `true` | | +| slave.readinessProbe.failureThreshold | int | `5` | | +| slave.readinessProbe.initialDelaySeconds | int | `5` | | +| slave.readinessProbe.periodSeconds | int | `10` | | +| slave.readinessProbe.successThreshold | int | `1` | | +| slave.readinessProbe.timeoutSeconds | int | `10` | | +| slave.service.annotations | object | `{}` | | +| slave.service.labels | object | `{}` | | +| slave.service.loadBalancerIP | string | `nil` | | +| slave.service.port | int | `6379` | | +| slave.service.type | string | `"ClusterIP"` | | +| slave.statefulset.updateStrategy | string | `"RollingUpdate"` | | +| sysctlImage.command | list | `[]` | | +| sysctlImage.enabled | bool | `false` | | +| sysctlImage.mountHostSys | bool | `false` | | +| sysctlImage.pullPolicy | string | `"Always"` | | +| sysctlImage.registry | string | `"docker.io"` | | +| sysctlImage.repository | string | `"bitnami/minideb"` | | +| sysctlImage.resources | object | `{}` | | +| sysctlImage.tag | string | `"buster"` | | +| usePassword | bool | `false` | | +| usePasswordFile | bool | `false` | | +| volumePermissions.enabled | bool | `false` | | +| volumePermissions.image.pullPolicy | string | `"Always"` | | +| volumePermissions.image.registry | string | `"docker.io"` | | +| volumePermissions.image.repository | string | `"bitnami/minideb"` | | +| volumePermissions.image.tag | string | `"buster"` | | +| volumePermissions.resources | object | `{}` | | diff --git a/infra/charts/feast/charts/redis/ci/default-values.yaml b/infra/charts/feast/charts/redis/ci/default-values.yaml new file mode 100644 index 00000000000..fc2ba605ada --- /dev/null +++ b/infra/charts/feast/charts/redis/ci/default-values.yaml @@ -0,0 +1 @@ +# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/infra/charts/feast/charts/redis/ci/dev-values.yaml b/infra/charts/feast/charts/redis/ci/dev-values.yaml new file mode 100644 index 00000000000..be01913b5b5 --- /dev/null +++ b/infra/charts/feast/charts/redis/ci/dev-values.yaml @@ -0,0 +1,9 @@ +master: + persistence: + enabled: false + +cluster: + enabled: true + slaveCount: 1 + +usePassword: false diff --git a/infra/charts/feast/charts/redis/ci/extra-flags-values.yaml b/infra/charts/feast/charts/redis/ci/extra-flags-values.yaml new file mode 100644 index 00000000000..71132f76e19 --- /dev/null +++ b/infra/charts/feast/charts/redis/ci/extra-flags-values.yaml @@ -0,0 +1,11 @@ +master: + extraFlags: + - --maxmemory-policy allkeys-lru + persistence: + enabled: false +slave: + extraFlags: + - --maxmemory-policy allkeys-lru + persistence: + enabled: false +usePassword: false diff --git a/infra/charts/feast/charts/redis/ci/insecure-sentinel-values.yaml b/infra/charts/feast/charts/redis/ci/insecure-sentinel-values.yaml new file mode 100644 index 00000000000..2e9174f4954 --- /dev/null +++ b/infra/charts/feast/charts/redis/ci/insecure-sentinel-values.yaml @@ -0,0 +1,524 @@ +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName + +## Bitnami Redis image version +## ref: https://hub.docker.com/r/bitnami/redis/tags/ +## +image: + registry: docker.io + repository: bitnami/redis + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.5-debian-9-r36 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +## Redis pod Security Context +securityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + +## Cluster settings +cluster: + enabled: true + slaveCount: 3 + +## Use redis sentinel in the redis pod. This will disable the master and slave services and +## create one redis service with ports to the sentinel and the redis instances +sentinel: + enabled: true + ## Require password authentication on the sentinel itself + ## ref: https://redis.io/topics/sentinel + usePassword: false + ## Bitnami Redis Sentintel image version + ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ + ## + image: + registry: docker.io + repository: bitnami/redis-sentinel + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.5-debian-9-r37 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + masterSet: mymaster + initialCheckTimeout: 5 + quorum: 2 + downAfterMilliseconds: 60000 + failoverTimeout: 18000 + parallelSyncs: 1 + port: 26379 + ## Configure extra options for Redis Sentinel liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + ## Redis Sentinel resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Redis Sentinel Service properties + service: + ## Redis Sentinel Service type + type: ClusterIP + sentinelPort: 26379 + redisPort: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # sentinelNodePort: + # redisNodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + +networkPolicy: + ## Specifies whether a NetworkPolicy should be created + ## + enabled: true + + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to the port Redis is listening + ## on. When true, Redis will accept connections from any source + ## (with the correct destination port). + ## + # allowExternal: true + +serviceAccount: + ## Specifies whether a ServiceAccount should be created + ## + create: false + ## The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the fullname template + name: + +rbac: + ## Specifies whether RBAC resources should be created + ## + create: false + + role: + ## Rules to create. It follows the role specification + # rules: + # - apiGroups: + # - extensions + # resources: + # - podsecuritypolicies + # verbs: + # - use + # resourceNames: + # - gce.unprivileged + rules: [] + + +## Use password authentication +usePassword: true +## Redis password (both master and slave) +## Defaults to a random 10-character alphanumeric string if not set and usePassword is true +## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run +## +password: +## Use existing secret (ignores previous password) +# existingSecret: +## Password key to be retrieved from Redis secret +## +# existingSecretPasswordKey: + +## Mount secrets as files instead of environment variables +usePasswordFile: false + +## Persist data to a persistent volume +persistence: {} + ## A manually managed Persistent Volume and Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + # existingClaim: + +# Redis port +redisPort: 6379 + +## +## Redis Master parameters +## +master: + ## Redis command arguments + ## + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Redis additional command line flags + ## + ## Can be used to specify command line flags, for example: + ## + ## extraFlags: + ## - "--maxmemory-policy volatile-ttl" + ## - "--repl-backlog-size 1024mb" + extraFlags: [] + ## Comma-separated list of Redis commands to disable + ## + ## Can be used to disable Redis commands for security reasons. + ## Commands will be completely disabled by renaming each to an empty string. + ## ref: https://redis.io/topics/security#disabling-of-specific-commands + ## + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Master additional pod labels and annotations + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + podAnnotations: {} + + ## Redis Master resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Configure extra options for Redis Master liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + + ## Redis Master Node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + ## Redis Master pod/node affinity/anti-affinity + ## + affinity: {} + + ## Redis Master Service properties + service: + ## Redis Master Service type + type: ClusterIP + port: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + + ## Redis Master pod priorityClassName + # priorityClassName: {} + + +## +## Redis Slave properties +## Note: service.type is a mandatory parameter +## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master +## +slave: + ## Slave Service properties + service: + ## Redis Slave Service type + type: ClusterIP + ## Redis port + port: 6379 + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + + ## Redis slave port + port: 6379 + + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Redis extra flags + extraFlags: [] + ## List of Redis commands to disable + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Slave pod/node affinity/anti-affinity + ## + affinity: {} + + ## Configure extra options for Redis Slave liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 5 + + ## Redis slave Resource + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + + ## Redis slave selectors and tolerations for pod assignment + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Redis slave pod Annotation and Labels + podLabels: {} + podAnnotations: {} + + ## Redis slave pod priorityClassName + # priorityClassName: {} + +## Prometheus Exporter / Metrics +## +metrics: + enabled: true + + image: + registry: docker.io + repository: bitnami/redis-exporter + tag: 1.0.3-debian-9-r0 + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + + ## Metrics exporter resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + # resources: {} + ## Metrics exporter pod priorityClassName + # priorityClassName: {} + service: + type: ClusterIP + ## Use serviceLoadBalancerIP to request a specific static IP, + ## otherwise leave blank + # loadBalancerIP: + annotations: {} + + ## Extra arguments for Metrics exporter, for example: + ## extraArgs: + ## check-keys: myKey,myOtherKey + # extraArgs: {} + + ## Metrics exporter pod Annotation and Labels + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9121" + # podLabels: {} + + # Enable this if you're using https://github.com/coreos/prometheus-operator + serviceMonitor: + enabled: false + ## Specify a namespace if needed + # namespace: monitoring + # fallback to the prometheus default unless specified + # interval: 10s + ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) + ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) + ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) + selector: + prometheus: kube-prometheus +## +## Init containers parameters: +## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup +## +volumePermissions: + enabled: false + image: + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + +## Redis config file +## ref: https://redis.io/topics/config +## +configmap: |- + # maxmemory-policy volatile-lru + +## Sysctl InitContainer +## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) +sysctlImage: + enabled: false + command: [] + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + mountHostSys: false + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m diff --git a/infra/charts/feast/charts/redis/ci/production-sentinel-values.yaml b/infra/charts/feast/charts/redis/ci/production-sentinel-values.yaml new file mode 100644 index 00000000000..36a00e37fb9 --- /dev/null +++ b/infra/charts/feast/charts/redis/ci/production-sentinel-values.yaml @@ -0,0 +1,524 @@ +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName + +## Bitnami Redis image version +## ref: https://hub.docker.com/r/bitnami/redis/tags/ +## +image: + registry: docker.io + repository: bitnami/redis + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.5-debian-9-r36 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +## Redis pod Security Context +securityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + +## Cluster settings +cluster: + enabled: true + slaveCount: 3 + +## Use redis sentinel in the redis pod. This will disable the master and slave services and +## create one redis service with ports to the sentinel and the redis instances +sentinel: + enabled: true + ## Require password authentication on the sentinel itself + ## ref: https://redis.io/topics/sentinel + usePassword: true + ## Bitnami Redis Sentintel image version + ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ + ## + image: + registry: docker.io + repository: bitnami/redis-sentinel + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.5-debian-9-r37 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + masterSet: mymaster + initialCheckTimeout: 5 + quorum: 2 + downAfterMilliseconds: 60000 + failoverTimeout: 18000 + parallelSyncs: 1 + port: 26379 + ## Configure extra options for Redis Sentinel liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + ## Redis Sentinel resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Redis Sentinel Service properties + service: + ## Redis Sentinel Service type + type: ClusterIP + sentinelPort: 26379 + redisPort: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # sentinelNodePort: + # redisNodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + +networkPolicy: + ## Specifies whether a NetworkPolicy should be created + ## + enabled: true + + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to the port Redis is listening + ## on. When true, Redis will accept connections from any source + ## (with the correct destination port). + ## + # allowExternal: true + +serviceAccount: + ## Specifies whether a ServiceAccount should be created + ## + create: false + ## The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the fullname template + name: + +rbac: + ## Specifies whether RBAC resources should be created + ## + create: false + + role: + ## Rules to create. It follows the role specification + # rules: + # - apiGroups: + # - extensions + # resources: + # - podsecuritypolicies + # verbs: + # - use + # resourceNames: + # - gce.unprivileged + rules: [] + + +## Use password authentication +usePassword: true +## Redis password (both master and slave) +## Defaults to a random 10-character alphanumeric string if not set and usePassword is true +## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run +## +password: +## Use existing secret (ignores previous password) +# existingSecret: +## Password key to be retrieved from Redis secret +## +# existingSecretPasswordKey: + +## Mount secrets as files instead of environment variables +usePasswordFile: false + +## Persist data to a persistent volume +persistence: {} + ## A manually managed Persistent Volume and Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + # existingClaim: + +# Redis port +redisPort: 6379 + +## +## Redis Master parameters +## +master: + ## Redis command arguments + ## + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Redis additional command line flags + ## + ## Can be used to specify command line flags, for example: + ## + ## extraFlags: + ## - "--maxmemory-policy volatile-ttl" + ## - "--repl-backlog-size 1024mb" + extraFlags: [] + ## Comma-separated list of Redis commands to disable + ## + ## Can be used to disable Redis commands for security reasons. + ## Commands will be completely disabled by renaming each to an empty string. + ## ref: https://redis.io/topics/security#disabling-of-specific-commands + ## + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Master additional pod labels and annotations + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + podAnnotations: {} + + ## Redis Master resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Configure extra options for Redis Master liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + + ## Redis Master Node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + ## Redis Master pod/node affinity/anti-affinity + ## + affinity: {} + + ## Redis Master Service properties + service: + ## Redis Master Service type + type: ClusterIP + port: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + + ## Redis Master pod priorityClassName + # priorityClassName: {} + + +## +## Redis Slave properties +## Note: service.type is a mandatory parameter +## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master +## +slave: + ## Slave Service properties + service: + ## Redis Slave Service type + type: ClusterIP + ## Redis port + port: 6379 + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + + ## Redis slave port + port: 6379 + + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Redis extra flags + extraFlags: [] + ## List of Redis commands to disable + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Slave pod/node affinity/anti-affinity + ## + affinity: {} + + ## Configure extra options for Redis Slave liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 5 + + ## Redis slave Resource + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + + ## Redis slave selectors and tolerations for pod assignment + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Redis slave pod Annotation and Labels + podLabels: {} + podAnnotations: {} + + ## Redis slave pod priorityClassName + # priorityClassName: {} + +## Prometheus Exporter / Metrics +## +metrics: + enabled: true + + image: + registry: docker.io + repository: bitnami/redis-exporter + tag: 1.0.3-debian-9-r0 + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + + ## Metrics exporter resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + # resources: {} + ## Metrics exporter pod priorityClassName + # priorityClassName: {} + service: + type: ClusterIP + ## Use serviceLoadBalancerIP to request a specific static IP, + ## otherwise leave blank + # loadBalancerIP: + annotations: {} + + ## Extra arguments for Metrics exporter, for example: + ## extraArgs: + ## check-keys: myKey,myOtherKey + # extraArgs: {} + + ## Metrics exporter pod Annotation and Labels + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9121" + # podLabels: {} + + # Enable this if you're using https://github.com/coreos/prometheus-operator + serviceMonitor: + enabled: false + ## Specify a namespace if needed + # namespace: monitoring + # fallback to the prometheus default unless specified + # interval: 10s + ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) + ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) + ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) + selector: + prometheus: kube-prometheus +## +## Init containers parameters: +## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup +## +volumePermissions: + enabled: false + image: + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + +## Redis config file +## ref: https://redis.io/topics/config +## +configmap: |- + # maxmemory-policy volatile-lru + +## Sysctl InitContainer +## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) +sysctlImage: + enabled: false + command: [] + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + mountHostSys: false + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m diff --git a/infra/charts/feast/charts/redis/ci/production-values.yaml b/infra/charts/feast/charts/redis/ci/production-values.yaml new file mode 100644 index 00000000000..6fa9c88ad3b --- /dev/null +++ b/infra/charts/feast/charts/redis/ci/production-values.yaml @@ -0,0 +1,525 @@ +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName + +## Bitnami Redis image version +## ref: https://hub.docker.com/r/bitnami/redis/tags/ +## +image: + registry: docker.io + repository: bitnami/redis + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.5-debian-9-r36 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +## Redis pod Security Context +securityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + +## Cluster settings +cluster: + enabled: true + slaveCount: 3 + +## Use redis sentinel in the redis pod. This will disable the master and slave services and +## create one redis service with ports to the sentinel and the redis instances +sentinel: + enabled: false + ## Require password authentication on the sentinel itself + ## ref: https://redis.io/topics/sentinel + usePassword: true + ## Bitnami Redis Sentintel image version + ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ + ## + image: + registry: docker.io + repository: bitnami/redis-sentinel + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.5-debian-9-r37 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + masterSet: mymaster + initialCheckTimeout: 5 + quorum: 2 + downAfterMilliseconds: 60000 + failoverTimeout: 18000 + parallelSyncs: 1 + port: 26379 + ## Configure extra options for Redis Sentinel liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + ## Redis Sentinel resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Redis Sentinel Service properties + service: + ## Redis Sentinel Service type + type: ClusterIP + sentinelPort: 26379 + redisPort: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # sentinelNodePort: + # redisNodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + +networkPolicy: + ## Specifies whether a NetworkPolicy should be created + ## + enabled: true + + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to the port Redis is listening + ## on. When true, Redis will accept connections from any source + ## (with the correct destination port). + ## + # allowExternal: true + +serviceAccount: + ## Specifies whether a ServiceAccount should be created + ## + create: false + ## The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the fullname template + name: + +rbac: + ## Specifies whether RBAC resources should be created + ## + create: false + + role: + ## Rules to create. It follows the role specification + # rules: + # - apiGroups: + # - extensions + # resources: + # - podsecuritypolicies + # verbs: + # - use + # resourceNames: + # - gce.unprivileged + rules: [] + + +## Use password authentication +usePassword: true +## Redis password (both master and slave) +## Defaults to a random 10-character alphanumeric string if not set and usePassword is true +## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run +## +password: +## Use existing secret (ignores previous password) +# existingSecret: +## Password key to be retrieved from Redis secret +## +# existingSecretPasswordKey: + +## Mount secrets as files instead of environment variables +usePasswordFile: false + +## Persist data to a persistent volume +persistence: {} + ## A manually managed Persistent Volume and Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + # existingClaim: + +# Redis port +redisPort: 6379 + +## +## Redis Master parameters +## +master: + ## Redis command arguments + ## + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Redis additional command line flags + ## + ## Can be used to specify command line flags, for example: + ## + ## extraFlags: + ## - "--maxmemory-policy volatile-ttl" + ## - "--repl-backlog-size 1024mb" + extraFlags: [] + ## Comma-separated list of Redis commands to disable + ## + ## Can be used to disable Redis commands for security reasons. + ## Commands will be completely disabled by renaming each to an empty string. + ## ref: https://redis.io/topics/security#disabling-of-specific-commands + ## + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Master additional pod labels and annotations + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + podAnnotations: {} + + ## Redis Master resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Configure extra options for Redis Master liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + + ## Redis Master Node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + ## Redis Master pod/node affinity/anti-affinity + ## + affinity: {} + + ## Redis Master Service properties + service: + ## Redis Master Service type + type: ClusterIP + port: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + + ## Redis Master pod priorityClassName + # priorityClassName: {} + + +## +## Redis Slave properties +## Note: service.type is a mandatory parameter +## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master +## +slave: + ## Slave Service properties + service: + ## Redis Slave Service type + type: ClusterIP + ## Redis port + port: 6379 + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + loadBalancerIP: + + ## Redis slave port + port: 6379 + + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Redis extra flags + extraFlags: [] + ## List of Redis commands to disable + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Slave pod/node affinity/anti-affinity + ## + affinity: {} + + ## Configure extra options for Redis Slave liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 5 + + ## Redis slave Resource + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + + ## Redis slave selectors and tolerations for pod assignment + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Redis slave pod Annotation and Labels + podLabels: {} + podAnnotations: {} + + ## Redis slave pod priorityClassName + # priorityClassName: {} + +## Prometheus Exporter / Metrics +## +metrics: + enabled: true + + image: + registry: docker.io + repository: bitnami/redis-exporter + tag: 1.0.3-debian-9-r0 + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + + ## Metrics exporter resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + # resources: {} + + ## Extra arguments for Metrics exporter, for example: + ## extraArgs: + ## check-keys: myKey,myOtherKey + # extraArgs: {} + ## Metrics exporter pod priorityClassName + # priorityClassName: {} + service: + type: ClusterIP + ## Use serviceLoadBalancerIP to request a specific static IP, + ## otherwise leave blank + # loadBalancerIP: + annotations: {} + + ## Metrics exporter pod Annotation and Labels + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9121" + # podLabels: {} + + # Enable this if you're using https://github.com/coreos/prometheus-operator + serviceMonitor: + enabled: false + ## Specify a namespace if needed + # namespace: monitoring + # fallback to the prometheus default unless specified + # interval: 10s + ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) + ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) + ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) + selector: + prometheus: kube-prometheus + +## +## Init containers parameters: +## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup +## +volumePermissions: + enabled: false + image: + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + +## Redis config file +## ref: https://redis.io/topics/config +## +configmap: |- + # maxmemory-policy volatile-lru + +## Sysctl InitContainer +## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) +sysctlImage: + enabled: false + command: [] + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + mountHostSys: false + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m diff --git a/infra/charts/feast/charts/redis/ci/redis-lib-values.yaml b/infra/charts/feast/charts/redis/ci/redis-lib-values.yaml new file mode 100644 index 00000000000..e03382b55ea --- /dev/null +++ b/infra/charts/feast/charts/redis/ci/redis-lib-values.yaml @@ -0,0 +1,13 @@ +## Redis library image +## ref: https://hub.docker.com/r/library/redis/ +## +image: + registry: docker.io + repository: redis + tag: '5.0.5' + +master: + command: "redis-server" + +slave: + command: "redis-server" diff --git a/infra/charts/feast/charts/redis/ci/redisgraph-module-values.yaml b/infra/charts/feast/charts/redis/ci/redisgraph-module-values.yaml new file mode 100644 index 00000000000..80960203ca0 --- /dev/null +++ b/infra/charts/feast/charts/redis/ci/redisgraph-module-values.yaml @@ -0,0 +1,10 @@ +image: + registry: docker.io + repository: redislabs/redisgraph + tag: '1.0.0' + +master: + command: "redis-server" + +slave: + command: "redis-server" diff --git a/infra/charts/feast/charts/redis/templates/NOTES.txt b/infra/charts/feast/charts/redis/templates/NOTES.txt new file mode 100644 index 00000000000..5b1089e8bec --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/NOTES.txt @@ -0,0 +1,104 @@ +** Please be patient while the chart is being deployed ** + +{{- if contains .Values.master.service.type "LoadBalancer" }} +{{- if not .Values.usePassword }} +{{ if and (not .Values.networkPolicy.enabled) (.Values.networkPolicy.allowExternal) }} + +------------------------------------------------------------------------------- + WARNING + + By specifying "master.service.type=LoadBalancer" and "usePassword=false" you have + most likely exposed the Redis service externally without any authentication + mechanism. + + For security reasons, we strongly suggest that you switch to "ClusterIP" or + "NodePort". As alternative, you can also switch to "usePassword=true" + providing a valid password on "password" parameter. + +------------------------------------------------------------------------------- +{{- end }} +{{- end }} +{{- end }} + +{{- if .Values.cluster.enabled }} +{{- if .Values.sentinel.enabled }} +Redis can be accessed via port {{ .Values.sentinel.service.redisPort }} on the following DNS name from within your cluster: + +{{ template "redis.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read only operations + +For read/write operations, first access the Redis Sentinel cluster, which is available in port {{ .Values.sentinel.service.sentinelPort }} using the same domain name above. + +{{- else }} +Redis can be accessed via port {{ .Values.redisPort }} on the following DNS names from within your cluster: + +{{ template "redis.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read/write operations +{{ template "redis.fullname" . }}-slave.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read-only operations +{{- end }} + +{{- else }} +Redis can be accessed via port {{ .Values.redisPort }} on the following DNS name from within your cluster: + +{{ template "redis.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + +{{- end }} + +{{ if .Values.usePassword }} +To get your password run: + + export REDIS_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "redis.secretName" . }} -o jsonpath="{.data.redis-password}" | base64 --decode) +{{- end }} + +To connect to your Redis server: + +1. Run a Redis pod that you can use as a client: + + kubectl run --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }}-client --rm --tty -i --restart='Never' \ + {{ if .Values.usePassword }} --env REDIS_PASSWORD=$REDIS_PASSWORD \{{ end }} + {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}--labels="{{ template "redis.fullname" . }}-client=true" \{{- end }} + --image {{ template "redis.image" . }} -- bash + +2. Connect using the Redis CLI: + +{{- if .Values.cluster.enabled }} + {{- if .Values.sentinel.enabled }} + redis-cli -h {{ template "redis.fullname" . }} -p {{ .Values.sentinel.service.redisPort }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} # Read only operations + redis-cli -h {{ template "redis.fullname" . }} -p {{ .Values.sentinel.service.sentinelPort }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} # Sentinel access + {{- else }} + redis-cli -h {{ template "redis.fullname" . }}-master{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} + redis-cli -h {{ template "redis.fullname" . }}-slave{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} + {{- end }} +{{- else }} + redis-cli -h {{ template "redis.fullname" . }}-master{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} +{{- end }} + +{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} +Note: Since NetworkPolicy is enabled, only pods with label +{{ template "redis.fullname" . }}-client=true" +will be able to connect to redis. +{{- else -}} + +To connect to your database from outside the cluster execute the following commands: + +{{- if contains "NodePort" .Values.master.service.type }} + + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "redis.fullname" . }}-master) + redis-cli -h $NODE_IP -p $NODE_PORT {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} + +{{- else if contains "LoadBalancer" .Values.master.service.type }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "redis.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + redis-cli -h $SERVICE_IP -p {{ .Values.master.service.port }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} + +{{- else if contains "ClusterIP" .Values.master.service.type }} + + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "redis.fullname" . }}-master {{ .Values.redisPort }}:{{ .Values.redisPort }} & + redis-cli -h 127.0.0.1 -p {{ .Values.redisPort }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} + +{{- end }} +{{- end }} + +{{ include "redis.checkRollingTags" . }} diff --git a/infra/charts/feast/charts/redis/templates/_helpers.tpl b/infra/charts/feast/charts/redis/templates/_helpers.tpl new file mode 100644 index 00000000000..3397a7b6c70 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/_helpers.tpl @@ -0,0 +1,355 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "redis.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the chart plus release name (used by the chart label) +*/}} +{{- define "redis.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version -}} +{{- 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 "redis.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 -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "networkPolicy.apiVersion" -}} +{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiGroup for PodSecurityPolicy. +*/}} +{{- define "podSecurityPolicy.apiGroup" -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "policy" -}} +{{- else -}} +{{- print "extensions" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for PodSecurityPolicy. +*/}} +{{- define "podSecurityPolicy.apiVersion" -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "extensions/v1beta1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Redis image name +*/}} +{{- define "redis.image" -}} +{{- $registryName := .Values.image.registry -}} +{{- $repositoryName := .Values.image.repository -}} +{{- $tag := .Values.image.tag | toString -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. +Also, we can't use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} + {{- if .Values.global.imageRegistry }} + {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} + {{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} + {{- end -}} +{{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Redis Sentinel image name +*/}} +{{- define "sentinel.image" -}} +{{- $registryName := .Values.sentinel.image.registry -}} +{{- $repositoryName := .Values.sentinel.image.repository -}} +{{- $tag := .Values.sentinel.image.tag | toString -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. +Also, we can't use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} + {{- if .Values.global.imageRegistry }} + {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} + {{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} + {{- end -}} +{{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper image name (for the metrics image) +*/}} +{{- define "redis.metrics.image" -}} +{{- $registryName := .Values.metrics.image.registry -}} +{{- $repositoryName := .Values.metrics.image.repository -}} +{{- $tag := .Values.metrics.image.tag | toString -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. +Also, we can't use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} + {{- if .Values.global.imageRegistry }} + {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} + {{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} + {{- end -}} +{{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "redis.volumePermissions.image" -}} +{{- $registryName := .Values.volumePermissions.image.registry -}} +{{- $repositoryName := .Values.volumePermissions.image.repository -}} +{{- $tag := .Values.volumePermissions.image.tag | toString -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. +Also, we can't use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} + {{- if .Values.global.imageRegistry }} + {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} + {{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} + {{- end -}} +{{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "redis.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "redis.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Get the password secret. +*/}} +{{- define "redis.secretName" -}} +{{- if .Values.existingSecret -}} +{{- printf "%s" .Values.existingSecret -}} +{{- else -}} +{{- printf "%s" (include "redis.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Get the password key to be retrieved from Redis secret. +*/}} +{{- define "redis.secretPasswordKey" -}} +{{- if and .Values.existingSecret .Values.existingSecretPasswordKey -}} +{{- printf "%s" .Values.existingSecretPasswordKey -}} +{{- else -}} +{{- printf "redis-password" -}} +{{- end -}} +{{- end -}} + +{{/* +Return Redis password +*/}} +{{- define "redis.password" -}} +{{- if not (empty .Values.global.redis.password) }} + {{- .Values.global.redis.password -}} +{{- else if not (empty .Values.password) -}} + {{- .Values.password -}} +{{- else -}} + {{- randAlphaNum 10 -}} +{{- end -}} +{{- end -}} + +{{/* +Return sysctl image +*/}} +{{- define "redis.sysctl.image" -}} +{{- $registryName := default "docker.io" .Values.sysctlImage.registry -}} +{{- $repositoryName := .Values.sysctlImage.repository -}} +{{- $tag := default "buster" .Values.sysctlImage.tag | toString -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. +Also, we can't use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} + {{- if .Values.global.imageRegistry }} + {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} + {{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} + {{- end -}} +{{- else -}} + {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "redis.imagePullSecrets" -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. +Also, we can not use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets .Values.sysctlImage.pullSecrets .Values.volumePermissions.image.pullSecrets }} +imagePullSecrets: +{{- range .Values.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.metrics.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.sysctlImage.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.volumePermissions.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- end -}} +{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets .Values.sysctlImage.pullSecrets .Values.volumePermissions.image.pullSecrets }} +imagePullSecrets: +{{- range .Values.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.metrics.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.sysctlImage.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- range .Values.volumePermissions.image.pullSecrets }} + - name: {{ . }} +{{- end }} +{{- end -}} +{{- end -}} + +{{/* Check if there are rolling tags in the images */}} +{{- define "redis.checkRollingTags" -}} +{{- if and (contains "bitnami/" .Values.image.repository) (not (.Values.image.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .Values.image.repository }}:{{ .Values.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ +{{- end }} +{{- if and (contains "bitnami/" .Values.sentinel.image.repository) (not (.Values.sentinel.image.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .Values.sentinel.image.repository }}:{{ .Values.sentinel.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ +{{- end }} +{{- end -}} + +{{/* +Return the proper Storage Class for master +*/}} +{{- define "redis.master.storageClass" -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. +*/}} +{{- if .Values.global -}} + {{- if .Values.global.storageClass -}} + {{- if (eq "-" .Values.global.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.global.storageClass -}} + {{- end -}} + {{- else -}} + {{- if .Values.master.persistence.storageClass -}} + {{- if (eq "-" .Values.master.persistence.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.master.persistence.storageClass -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- else -}} + {{- if .Values.master.persistence.storageClass -}} + {{- if (eq "-" .Values.master.persistence.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.master.persistence.storageClass -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Storage Class for slave +*/}} +{{- define "redis.slave.storageClass" -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. +*/}} +{{- if .Values.global -}} + {{- if .Values.global.storageClass -}} + {{- if (eq "-" .Values.global.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.global.storageClass -}} + {{- end -}} + {{- else -}} + {{- if .Values.slave.persistence.storageClass -}} + {{- if (eq "-" .Values.slave.persistence.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.slave.persistence.storageClass -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- else -}} + {{- if .Values.slave.persistence.storageClass -}} + {{- if (eq "-" .Values.slave.persistence.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" .Values.slave.persistence.storageClass -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/configmap.yaml b/infra/charts/feast/charts/redis/templates/configmap.yaml new file mode 100644 index 00000000000..d17ec26abf9 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/configmap.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "redis.fullname" . }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +data: + redis.conf: |- +{{- if .Values.configmap }} + # User-supplied configuration: +{{ tpl .Values.configmap . | indent 4 }} +{{- end }} + master.conf: |- + dir {{ .Values.master.persistence.path }} +{{- if .Values.master.configmap }} + # User-supplied master configuration: +{{ tpl .Values.master.configmap . | indent 4 }} +{{- end }} +{{- if .Values.master.disableCommands }} +{{- range .Values.master.disableCommands }} + rename-command {{ . }} "" +{{- end }} +{{- end }} + replica.conf: |- + dir {{ .Values.slave.persistence.path }} + slave-read-only yes +{{- if .Values.slave.configmap }} + # User-supplied slave configuration: +{{ tpl .Values.slave.configmap . | indent 4 }} +{{- end }} +{{- if .Values.slave.disableCommands }} +{{- range .Values.slave.disableCommands }} + rename-command {{ . }} "" +{{- end }} +{{- end }} +{{- if .Values.sentinel.enabled }} + sentinel.conf: |- + dir "/tmp" + bind 0.0.0.0 + port {{ .Values.sentinel.port }} + sentinel monitor {{ .Values.sentinel.masterSet }} {{ template "redis.fullname" . }}-master-0.{{ template "redis.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} {{ .Values.redisPort }} {{ .Values.sentinel.quorum }} + sentinel down-after-milliseconds {{ .Values.sentinel.masterSet }} {{ .Values.sentinel.downAfterMilliseconds }} + sentinel failover-timeout {{ .Values.sentinel.masterSet }} {{ .Values.sentinel.failoverTimeout }} + sentinel parallel-syncs {{ .Values.sentinel.masterSet }} {{ .Values.sentinel.parallelSyncs }} +{{- if .Values.sentinel.configmap }} + # User-supplied sentinel configuration: +{{ tpl .Values.sentinel.configmap . | indent 4 }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/headless-svc.yaml b/infra/charts/feast/charts/redis/templates/headless-svc.yaml new file mode 100644 index 00000000000..909cbceafd1 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/headless-svc.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "redis.fullname" . }}-headless + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: redis + port: {{ .Values.redisPort }} + targetPort: redis +{{- if .Values.sentinel.enabled }} + - name: redis-sentinel + port: {{ .Values.sentinel.port }} + targetPort: redis-sentinel +{{- end }} + selector: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} diff --git a/infra/charts/feast/charts/redis/templates/health-configmap.yaml b/infra/charts/feast/charts/redis/templates/health-configmap.yaml new file mode 100644 index 00000000000..35c61b5ad20 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/health-configmap.yaml @@ -0,0 +1,134 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "redis.fullname" . }}-health + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +data: + ping_readiness_local.sh: |- +{{- if .Values.usePasswordFile }} + password_aux=`cat ${REDIS_PASSWORD_FILE}` + export REDIS_PASSWORD=$password_aux +{{- end }} + response=$( + timeout -s 9 $1 \ + redis-cli \ +{{- if .Values.usePassword }} + -a $REDIS_PASSWORD --no-auth-warning \ +{{- end }} + -h localhost \ + -p $REDIS_PORT \ + ping + ) + if [ "$response" != "PONG" ]; then + echo "$response" + exit 1 + fi + ping_liveness_local.sh: |- +{{- if .Values.usePasswordFile }} + password_aux=`cat ${REDIS_PASSWORD_FILE}` + export REDIS_PASSWORD=$password_aux +{{- end }} + response=$( + timeout -s 9 $1 \ + redis-cli \ +{{- if .Values.usePassword }} + -a $REDIS_PASSWORD --no-auth-warning \ +{{- end }} + -h localhost \ + -p $REDIS_PORT \ + ping + ) + if [ "$response" != "PONG" ] && [ "$response" != "LOADING Redis is loading the dataset in memory" ]; then + echo "$response" + exit 1 + fi +{{- if .Values.sentinel.enabled }} + ping_sentinel.sh: |- +{{- if .Values.usePasswordFile }} + password_aux=`cat ${REDIS_PASSWORD_FILE}` + export REDIS_PASSWORD=$password_aux +{{- end }} + response=$( + timeout -s 9 $1 \ + redis-cli \ +{{- if .Values.usePassword }} + -a $REDIS_PASSWORD --no-auth-warning \ +{{- end }} + -h localhost \ + -p $REDIS_SENTINEL_PORT \ + ping + ) + if [ "$response" != "PONG" ]; then + echo "$response" + exit 1 + fi + parse_sentinels.awk: |- + /ip/ {FOUND_IP=1} + /port/ {FOUND_PORT=1} + /runid/ {FOUND_RUNID=1} + !/ip|port|runid/ { + if (FOUND_IP==1) { + IP=$1; FOUND_IP=0; + } + else if (FOUND_PORT==1) { + PORT=$1; + FOUND_PORT=0; + } else if (FOUND_RUNID==1) { + printf "\nsentinel known-sentinel {{ .Values.sentinel.masterSet }} %s %s %s", IP, PORT, $0; FOUND_RUNID=0; + } + } +{{- end }} + ping_readiness_master.sh: |- +{{- if .Values.usePasswordFile }} + password_aux=`cat ${REDIS_MASTER_PASSWORD_FILE}` + export REDIS_MASTER_PASSWORD=$password_aux +{{- end }} + response=$( + timeout -s 9 $1 \ + redis-cli \ +{{- if .Values.usePassword }} + -a $REDIS_MASTER_PASSWORD --no-auth-warning \ +{{- end }} + -h $REDIS_MASTER_HOST \ + -p $REDIS_MASTER_PORT_NUMBER \ + ping + ) + if [ "$response" != "PONG" ]; then + echo "$response" + exit 1 + fi + ping_liveness_master.sh: |- +{{- if .Values.usePasswordFile }} + password_aux=`cat ${REDIS_MASTER_PASSWORD_FILE}` + export REDIS_MASTER_PASSWORD=$password_aux +{{- end }} + response=$( + timeout -s 9 $1 \ + redis-cli \ +{{- if .Values.usePassword }} + -a $REDIS_MASTER_PASSWORD --no-auth-warning \ +{{- end }} + -h $REDIS_MASTER_HOST \ + -p $REDIS_MASTER_PORT_NUMBER \ + ping + ) + if [ "$response" != "PONG" ] && [ "$response" != "LOADING Redis is loading the dataset in memory" ]; then + echo "$response" + exit 1 + fi + ping_readiness_local_and_master.sh: |- + script_dir="$(dirname "$0")" + exit_status=0 + "$script_dir/ping_readiness_local.sh" $1 || exit_status=$? + "$script_dir/ping_readiness_master.sh" $1 || exit_status=$? + exit $exit_status + ping_liveness_local_and_master.sh: |- + script_dir="$(dirname "$0")" + exit_status=0 + "$script_dir/ping_liveness_local.sh" $1 || exit_status=$? + "$script_dir/ping_liveness_master.sh" $1 || exit_status=$? + exit $exit_status diff --git a/infra/charts/feast/charts/redis/templates/metrics-prometheus.yaml b/infra/charts/feast/charts/redis/templates/metrics-prometheus.yaml new file mode 100644 index 00000000000..3f3345430f9 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/metrics-prometheus.yaml @@ -0,0 +1,30 @@ +{{- if and (.Values.metrics.enabled) (.Values.metrics.serviceMonitor.enabled) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "redis.fullname" . }} + {{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- range $key, $value := .Values.metrics.serviceMonitor.selector }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + endpoints: + - port: metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + selector: + matchLabels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/metrics-svc.yaml b/infra/charts/feast/charts/redis/templates/metrics-svc.yaml new file mode 100644 index 00000000000..74f6fa85294 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/metrics-svc.yaml @@ -0,0 +1,30 @@ +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "redis.fullname" . }}-metrics + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.metrics.service.labels -}} + {{ toYaml .Values.metrics.service.labels | nindent 4 }} + {{- end -}} + {{- if .Values.metrics.service.annotations }} + annotations: {{ toYaml .Values.metrics.service.annotations | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.metrics.service.type }} + {{ if eq .Values.metrics.service.type "LoadBalancer" -}} {{ if .Values.metrics.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.metrics.service.loadBalancerIP }} + {{ end -}} + {{- end -}} + ports: + - name: metrics + port: 9121 + targetPort: metrics + selector: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/networkpolicy.yaml b/infra/charts/feast/charts/redis/templates/networkpolicy.yaml new file mode 100644 index 00000000000..da055527cc7 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/networkpolicy.yaml @@ -0,0 +1,73 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "networkPolicy.apiVersion" . }} +metadata: + name: {{ template "redis.fullname" . }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + podSelector: + matchLabels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + {{- if .Values.cluster.enabled }} + policyTypes: + - Ingress + - Egress + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + # Allow outbound connections to other cluster pods + - ports: + - port: {{ .Values.redisPort }} + {{- if .Values.sentinel.enabled }} + - port: {{ .Values.sentinel.port }} + {{- end }} + to: + - podSelector: + matchLabels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + {{- end }} + ingress: + # Allow inbound connections + - ports: + - port: {{ .Values.redisPort }} + {{- if .Values.sentinel.enabled }} + - port: {{ .Values.sentinel.port }} + {{- end }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "redis.fullname" . }}-client: "true" + - podSelector: + matchLabels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.metrics.enabled }} + # Allow prometheus scrapes for metrics + - ports: + - port: 9121 + {{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/prometheusrule.yaml b/infra/charts/feast/charts/redis/templates/prometheusrule.yaml new file mode 100644 index 00000000000..500c3b37e73 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/prometheusrule.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "redis.fullname" . }} +{{- with .Values.metrics.prometheusRule.namespace }} + namespace: {{ . }} +{{- end }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +{{- with .Values.metrics.prometheusRule.additionalLabels }} +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- with .Values.metrics.prometheusRule.rules }} + groups: + - name: {{ template "redis.name" $ }} + rules: {{ tpl (toYaml .) $ | nindent 8 }} +{{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/psp.yaml b/infra/charts/feast/charts/redis/templates/psp.yaml new file mode 100644 index 00000000000..28ae22a775a --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/psp.yaml @@ -0,0 +1,42 @@ +{{- if .Values.podSecurityPolicy.create }} +apiVersion: {{ template "podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "redis.fullname" . }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + allowPrivilegeEscalation: false + fsGroup: + rule: 'MustRunAs' + ranges: + - min: {{ .Values.securityContext.fsGroup }} + max: {{ .Values.securityContext.fsGroup }} + hostIPC: false + hostNetwork: false + hostPID: false + privileged: false + readOnlyRootFilesystem: false + requiredDropCapabilities: + - ALL + runAsUser: + rule: 'MustRunAs' + ranges: + - min: {{ .Values.securityContext.runAsUser }} + max: {{ .Values.securityContext.runAsUser }} + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: {{ .Values.securityContext.runAsUser }} + max: {{ .Values.securityContext.runAsUser }} + volumes: + - 'configMap' + - 'secret' + - 'emptyDir' + - 'persistentVolumeClaim' +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-master-statefulset.yaml b/infra/charts/feast/charts/redis/templates/redis-master-statefulset.yaml new file mode 100755 index 00000000000..b61c5391da7 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/redis-master-statefulset.yaml @@ -0,0 +1,419 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "redis.fullname" . }}-master + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + selector: + matchLabels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + role: master + serviceName: {{ template "redis.fullname" . }}-headless + template: + metadata: + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + role: master +{{- if .Values.master.podLabels }} +{{ toYaml .Values.master.podLabels | indent 8 }} +{{- end }} +{{- if and .Values.metrics.enabled .Values.metrics.podLabels }} +{{ toYaml .Values.metrics.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/health: {{ include (print $.Template.BasePath "/health-configmap.yaml") . | sha256sum }} + checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- if .Values.master.podAnnotations }} +{{ toYaml .Values.master.podAnnotations | indent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} +{{ toYaml .Values.metrics.podAnnotations | indent 8 }} + {{- end }} + spec: +{{- include "redis.imagePullSecrets" . | indent 6 }} + {{- if .Values.securityContext.enabled }} + securityContext: + fsGroup: {{ .Values.securityContext.fsGroup }} + {{- if .Values.securityContext.sysctls }} + sysctls: +{{ toYaml .Values.securityContext.sysctls | indent 8 }} + {{- end }} + {{- end }} + serviceAccountName: "{{ template "redis.serviceAccountName" . }}" + {{- if .Values.master.priorityClassName }} + priorityClassName: "{{ .Values.master.priorityClassName }}" + {{- end }} + {{- with .Values.master.affinity }} + affinity: +{{ tpl (toYaml .) $ | indent 8 }} + {{- end }} + {{- if .Values.master.nodeSelector }} + nodeSelector: +{{ toYaml .Values.master.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.master.tolerations }} + tolerations: +{{ toYaml .Values.master.tolerations | indent 8 }} + {{- end }} + {{- if .Values.master.schedulerName }} + schedulerName: "{{ .Values.master.schedulerName }}" + {{- end }} + containers: + - name: {{ template "redis.fullname" . }} + image: "{{ template "redis.image" . }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + command: + - /bin/bash + - -c + - | + {{- if (eq (.Values.securityContext.runAsUser | int) 0) }} + useradd redis + chown -R redis {{ .Values.master.persistence.path }} + {{- end }} + if [[ -n $REDIS_PASSWORD_FILE ]]; then + password_aux=`cat ${REDIS_PASSWORD_FILE}` + export REDIS_PASSWORD=$password_aux + fi + if [[ ! -f /opt/bitnami/redis/etc/master.conf ]];then + cp /opt/bitnami/redis/mounted-etc/master.conf /opt/bitnami/redis/etc/master.conf + fi + if [[ ! -f /opt/bitnami/redis/etc/redis.conf ]];then + cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf + fi + ARGS=("--port" "${REDIS_PORT}") + {{- if .Values.usePassword }} + ARGS+=("--requirepass" "${REDIS_PASSWORD}") + ARGS+=("--masterauth" "${REDIS_PASSWORD}") + {{- else }} + ARGS+=("--protected-mode" "no") + {{- end }} + ARGS+=("--include" "/opt/bitnami/redis/etc/redis.conf") + ARGS+=("--include" "/opt/bitnami/redis/etc/master.conf") + {{- if .Values.master.extraFlags }} + {{- range .Values.master.extraFlags }} + ARGS+=({{ . | quote }}) + {{- end }} + {{- end }} + {{- if .Values.master.command }} + {{ .Values.master.command }} ${ARGS[@]} + {{- else }} + redis-server "${ARGS[@]}" + {{- end }} + env: + - name: REDIS_REPLICATION_MODE + value: master + {{- if .Values.usePassword }} + {{- if .Values.usePasswordFile }} + - name: REDIS_PASSWORD_FILE + value: "/opt/bitnami/redis/secrets/redis-password" + {{- else }} + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "redis.secretName" . }} + key: {{ template "redis.secretPasswordKey" . }} + {{- end }} + {{- else }} + - name: ALLOW_EMPTY_PASSWORD + value: "yes" + {{- end }} + - name: REDIS_PORT + value: {{ .Values.redisPort | quote }} + ports: + - name: redis + containerPort: {{ .Values.redisPort }} + {{- if .Values.master.livenessProbe.enabled }} + livenessProbe: + initialDelaySeconds: {{ .Values.master.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.master.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.master.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.master.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.master.livenessProbe.failureThreshold }} + exec: + command: + - sh + - -c + - /health/ping_liveness_local.sh {{ .Values.master.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.master.readinessProbe.enabled}} + readinessProbe: + initialDelaySeconds: {{ .Values.master.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.master.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.master.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.master.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.master.readinessProbe.failureThreshold }} + exec: + command: + - sh + - -c + - /health/ping_readiness_local.sh {{ .Values.master.livenessProbe.timeoutSeconds }} + {{- end }} + resources: +{{ toYaml .Values.master.resources | indent 10 }} + volumeMounts: + - name: health + mountPath: /health + {{- if .Values.usePasswordFile }} + - name: redis-password + mountPath: /opt/bitnami/redis/secrets/ + {{- end }} + - name: redis-data + mountPath: {{ .Values.master.persistence.path }} + subPath: {{ .Values.master.persistence.subPath }} + - name: config + mountPath: /opt/bitnami/redis/mounted-etc + - name: redis-tmp-conf + mountPath: /opt/bitnami/redis/etc/ + {{- if and .Values.cluster.enabled .Values.sentinel.enabled }} + - name: sentinel + image: "{{ template "sentinel.image" . }}" + imagePullPolicy: {{ .Values.sentinel.image.pullPolicy | quote }} + {{- if .Values.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + command: + - /bin/bash + - -c + - | + if [[ -n $REDIS_PASSWORD_FILE ]]; then + password_aux=`cat ${REDIS_PASSWORD_FILE}` + export REDIS_PASSWORD=$password_aux + fi + if [[ ! -f /opt/bitnami/redis-sentinel/etc/sentinel.conf ]];then + cp /opt/bitnami/redis-sentinel/mounted-etc/sentinel.conf /opt/bitnami/redis-sentinel/etc/sentinel.conf + {{- if .Values.usePassword }} + printf "\nsentinel auth-pass {{ .Values.sentinel.masterSet }} $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf + {{- if .Values.sentinel.usePassword }} + printf "\nrequirepass $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf + {{- end }} + {{- end }} + {{- if .Values.sentinel.staticID }} + printf "\nsentinel myid $(echo $HOSTNAME | openssl sha1 | awk '{ print $2 }')" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf + {{- end }} + fi + echo "Getting information about current running sentinels" + # Get information from existing sentinels + existing_sentinels=$(timeout -s 9 {{ .Values.sentinel.initialCheckTimeout }} redis-cli --raw -h {{ template "redis.fullname" . }} -a "$REDIS_PASSWORD" -p {{ .Values.sentinel.service.sentinelPort }} SENTINEL sentinels {{ .Values.sentinel.masterSet }}) + echo "$existing_sentinels" | awk -f /health/parse_sentinels.awk | tee -a /opt/bitnami/redis-sentinel/etc/sentinel.conf + + redis-server /opt/bitnami/redis-sentinel/etc/sentinel.conf --sentinel + env: + {{- if .Values.usePassword }} + {{- if .Values.usePasswordFile }} + - name: REDIS_PASSWORD_FILE + value: "/opt/bitnami/redis/secrets/redis-password" + {{- else }} + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "redis.secretName" . }} + key: {{ template "redis.secretPasswordKey" . }} + {{- end }} + {{- else }} + - name: ALLOW_EMPTY_PASSWORD + value: "yes" + {{- end }} + - name: REDIS_SENTINEL_PORT + value: {{ .Values.sentinel.port | quote }} + ports: + - name: redis-sentinel + containerPort: {{ .Values.sentinel.port }} + {{- if .Values.sentinel.livenessProbe.enabled }} + livenessProbe: + initialDelaySeconds: {{ .Values.sentinel.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.sentinel.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.sentinel.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.sentinel.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.sentinel.livenessProbe.failureThreshold }} + exec: + command: + - sh + - -c + - /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.sentinel.readinessProbe.enabled}} + readinessProbe: + initialDelaySeconds: {{ .Values.sentinel.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.sentinel.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.sentinel.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.sentinel.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.sentinel.readinessProbe.failureThreshold }} + exec: + command: + - sh + - -c + - /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }} + {{- end }} + resources: +{{ toYaml .Values.sentinel.resources | indent 10 }} + volumeMounts: + - name: health + mountPath: /health + {{- if .Values.usePasswordFile }} + - name: redis-password + mountPath: /opt/bitnami/redis/secrets/ + {{- end }} + - name: redis-data + mountPath: {{ .Values.master.persistence.path }} + subPath: {{ .Values.master.persistence.subPath }} + - name: config + mountPath: /opt/bitnami/redis-sentinel/mounted-etc + - name: sentinel-tmp-conf + mountPath: /opt/bitnami/redis-sentinel/etc/ + {{- end }} +{{- if .Values.metrics.enabled }} + - name: metrics + image: {{ template "redis.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + command: + - /bin/bash + - -c + - | + if [[ -f '/secrets/redis-password' ]]; then + export REDIS_PASSWORD=$(cat /secrets/redis-password) + fi + redis_exporter{{- range $key, $value := .Values.metrics.extraArgs }} --{{ $key }}={{ $value }}{{- end }} + env: + - name: REDIS_ALIAS + value: {{ template "redis.fullname" . }} + {{- if and .Values.usePassword (not .Values.usePasswordFile) }} + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "redis.secretName" . }} + key: {{ template "redis.secretPasswordKey" . }} + {{- end }} + volumeMounts: + {{- if .Values.usePasswordFile }} + - name: redis-password + mountPath: /secrets/ + {{- end }} + ports: + - name: metrics + containerPort: 9121 + resources: +{{ toYaml .Values.metrics.resources | indent 10 }} +{{- end }} + {{- $needsVolumePermissions := and .Values.volumePermissions.enabled (and ( and .Values.master.persistence.enabled (not .Values.persistence.existingClaim) ) .Values.securityContext.enabled) }} + {{- if or $needsVolumePermissions .Values.sysctlImage.enabled }} + initContainers: + {{- if $needsVolumePermissions }} + - name: volume-permissions + image: "{{ template "redis.volumePermissions.image" . }}" + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: ["/bin/chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }}", "{{ .Values.master.persistence.path }}"] + securityContext: + runAsUser: 0 + resources: +{{ toYaml .Values.volumePermissions.resources | indent 10 }} + volumeMounts: + - name: redis-data + mountPath: {{ .Values.master.persistence.path }} + subPath: {{ .Values.master.persistence.subPath }} + {{- end }} + {{- if .Values.sysctlImage.enabled }} + - name: init-sysctl + image: {{ template "redis.sysctl.image" . }} + imagePullPolicy: {{ default "" .Values.sysctlImage.pullPolicy | quote }} + resources: +{{ toYaml .Values.sysctlImage.resources | indent 10 }} + {{- if .Values.sysctlImage.mountHostSys }} + volumeMounts: + - name: host-sys + mountPath: /host-sys + {{- end }} + command: +{{ toYaml .Values.sysctlImage.command | indent 10 }} + securityContext: + privileged: true + runAsUser: 0 + {{- end }} + {{- end }} + volumes: + - name: health + configMap: + name: {{ template "redis.fullname" . }}-health + defaultMode: 0755 + {{- if .Values.usePasswordFile }} + - name: redis-password + secret: + secretName: {{ template "redis.secretName" . }} + items: + - key: {{ template "redis.secretPasswordKey" . }} + path: redis-password + {{- end }} + - name: config + configMap: + name: {{ template "redis.fullname" . }} + {{- if not .Values.master.persistence.enabled }} + - name: "redis-data" + emptyDir: {} + {{- else }} + {{- if .Values.persistence.existingClaim }} + - name: "redis-data" + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim }} + {{- end }} + {{- end }} + {{- if .Values.sysctlImage.mountHostSys }} + - name: host-sys + hostPath: + path: /sys + {{- end }} + - name: redis-tmp-conf + emptyDir: {} + {{- if and .Values.cluster.enabled .Values.sentinel.enabled }} + - name: sentinel-tmp-conf + emptyDir: {} + {{- end }} + {{- if and .Values.master.persistence.enabled (not .Values.persistence.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: redis-data + labels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: master + spec: + accessModes: + {{- range .Values.master.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.master.persistence.size | quote }} + {{ include "redis.master.storageClass" . }} + selector: + {{- if .Values.master.persistence.matchLabels }} + matchLabels: +{{ toYaml .Values.master.persistence.matchLabels | indent 12 }} + {{- end -}} + {{- if .Values.master.persistence.matchExpressions }} + matchExpressions: +{{ toYaml .Values.master.persistence.matchExpressions | indent 12 }} + {{- end -}} + {{- end }} + updateStrategy: + type: {{ .Values.master.statefulset.updateStrategy }} + {{- if .Values.master.statefulset.rollingUpdatePartition }} + {{- if (eq "Recreate" .Values.master.statefulset.updateStrategy) }} + rollingUpdate: null + {{- else }} + rollingUpdate: + partition: {{ .Values.master.statefulset.rollingUpdatePartition }} + {{- end }} + {{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-master-svc.yaml b/infra/charts/feast/charts/redis/templates/redis-master-svc.yaml new file mode 100644 index 00000000000..3a98e667f03 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/redis-master-svc.yaml @@ -0,0 +1,39 @@ +{{- if not .Values.sentinel.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "redis.fullname" . }}-master + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.master.service.labels -}} + {{ toYaml .Values.master.service.labels | nindent 4 }} + {{- end -}} +{{- if .Values.master.service.annotations }} + annotations: {{ toYaml .Values.master.service.annotations | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.master.service.type }} + {{- if and (eq .Values.master.service.type "LoadBalancer") .Values.master.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.master.service.loadBalancerIP }} + {{- end }} + {{- if and (eq .Values.master.service.type "LoadBalancer") .Values.master.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- with .Values.master.service.loadBalancerSourceRanges }} +{{ toYaml . | indent 4 }} +{{- end }} + {{- end }} + ports: + - name: redis + port: {{ .Values.master.service.port }} + targetPort: redis + {{- if .Values.master.service.nodePort }} + nodePort: {{ .Values.master.service.nodePort }} + {{- end }} + selector: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + role: master +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-role.yaml b/infra/charts/feast/charts/redis/templates/redis-role.yaml new file mode 100644 index 00000000000..71f75ef78e6 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/redis-role.yaml @@ -0,0 +1,21 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "redis.fullname" . }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +rules: +{{- if .Values.podSecurityPolicy.create }} + - apiGroups: ['{{ template "podSecurityPolicy.apiGroup" . }}'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "redis.fullname" . }}] +{{- end -}} +{{- if .Values.rbac.role.rules }} +{{ toYaml .Values.rbac.role.rules | indent 2 }} +{{- end -}} +{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/redis-rolebinding.yaml b/infra/charts/feast/charts/redis/templates/redis-rolebinding.yaml new file mode 100644 index 00000000000..aceb258de62 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/redis-rolebinding.yaml @@ -0,0 +1,18 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "redis.fullname" . }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "redis.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "redis.serviceAccountName" . }} +{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/redis-serviceaccount.yaml b/infra/charts/feast/charts/redis/templates/redis-serviceaccount.yaml new file mode 100644 index 00000000000..f0271766006 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/redis-serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "redis.serviceAccountName" . }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/redis-slave-statefulset.yaml b/infra/charts/feast/charts/redis/templates/redis-slave-statefulset.yaml new file mode 100755 index 00000000000..d5a8db56159 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/redis-slave-statefulset.yaml @@ -0,0 +1,437 @@ +{{- if .Values.cluster.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "redis.fullname" . }}-slave + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: +{{- if .Values.slave.updateStrategy }} + strategy: +{{ toYaml .Values.slave.updateStrategy | indent 4 }} +{{- end }} + replicas: {{ .Values.cluster.slaveCount }} + serviceName: {{ template "redis.fullname" . }}-headless + selector: + matchLabels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + role: slave + template: + metadata: + labels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + chart: {{ template "redis.chart" . }} + role: slave + {{- if .Values.slave.podLabels }} +{{ toYaml .Values.slave.podLabels | indent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.podLabels }} +{{ toYaml .Values.metrics.podLabels | indent 8 }} + {{- end }} + annotations: + checksum/health: {{ include (print $.Template.BasePath "/health-configmap.yaml") . | sha256sum }} + checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- if .Values.slave.podAnnotations }} +{{ toYaml .Values.slave.podAnnotations | indent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} +{{ toYaml .Values.metrics.podAnnotations | indent 8 }} + {{- end }} + spec: +{{- include "redis.imagePullSecrets" . | indent 6 }} + {{- if .Values.securityContext.enabled }} + securityContext: + fsGroup: {{ .Values.securityContext.fsGroup }} + {{- if .Values.securityContext.sysctls }} + sysctls: +{{ toYaml .Values.securityContext.sysctls | indent 8 }} + {{- end }} + {{- end }} + serviceAccountName: "{{ template "redis.serviceAccountName" . }}" + {{- if .Values.slave.priorityClassName }} + priorityClassName: "{{ .Values.slave.priorityClassName }}" + {{- end }} + {{- if .Values.slave.nodeSelector }} + nodeSelector: +{{ toYaml .Values.slave.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.slave.tolerations }} + tolerations: +{{ toYaml .Values.slave.tolerations | indent 8 }} + {{- end }} + {{- if .Values.slave.schedulerName }} + schedulerName: "{{ .Values.slave.schedulerName }}" + {{- end }} + {{- with .Values.slave.affinity }} + affinity: +{{ tpl (toYaml .) $ | indent 8 }} + {{- end }} + containers: + - name: {{ template "redis.fullname" . }} + image: {{ template "redis.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + command: + - /bin/bash + - -c + - | + {{- if (eq (.Values.securityContext.runAsUser | int) 0) }} + useradd redis + chown -R redis {{ .Values.slave.persistence.path }} + {{- end }} + if [[ -n $REDIS_PASSWORD_FILE ]]; then + password_aux=`cat ${REDIS_PASSWORD_FILE}` + export REDIS_PASSWORD=$password_aux + fi + if [[ -n $REDIS_MASTER_PASSWORD_FILE ]]; then + password_aux=`cat ${REDIS_MASTER_PASSWORD_FILE}` + export REDIS_MASTER_PASSWORD=$password_aux + fi + if [[ ! -f /opt/bitnami/redis/etc/replica.conf ]];then + cp /opt/bitnami/redis/mounted-etc/replica.conf /opt/bitnami/redis/etc/replica.conf + fi + if [[ ! -f /opt/bitnami/redis/etc/redis.conf ]];then + cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf + fi + ARGS=("--port" "${REDIS_PORT}") + ARGS+=("--slaveof" "${REDIS_MASTER_HOST}" "${REDIS_MASTER_PORT_NUMBER}") + {{- if .Values.usePassword }} + ARGS+=("--requirepass" "${REDIS_PASSWORD}") + ARGS+=("--masterauth" "${REDIS_MASTER_PASSWORD}") + {{- else }} + ARGS+=("--protected-mode" "no") + {{- end }} + ARGS+=("--include" "/opt/bitnami/redis/etc/redis.conf") + ARGS+=("--include" "/opt/bitnami/redis/etc/replica.conf") + {{- if .Values.slave.extraFlags }} + {{- range .Values.slave.extraFlags }} + ARGS+=({{ . | quote }}) + {{- end }} + {{- end }} + {{- if .Values.slave.command }} + {{ .Values.slave.command }} "${ARGS[@]}" + {{- else }} + redis-server "${ARGS[@]}" + {{- end }} + env: + - name: REDIS_REPLICATION_MODE + value: slave + - name: REDIS_MASTER_HOST + value: {{ template "redis.fullname" . }}-master-0.{{ template "redis.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: REDIS_PORT + value: {{ .Values.redisPort | quote }} + - name: REDIS_MASTER_PORT_NUMBER + value: {{ .Values.redisPort | quote }} + {{- if .Values.usePassword }} + {{- if .Values.usePasswordFile }} + - name: REDIS_PASSWORD_FILE + value: "/opt/bitnami/redis/secrets/redis-password" + - name: REDIS_MASTER_PASSWORD_FILE + value: "/opt/bitnami/redis/secrets/redis-password" + {{- else }} + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "redis.secretName" . }} + key: {{ template "redis.secretPasswordKey" . }} + - name: REDIS_MASTER_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "redis.secretName" . }} + key: {{ template "redis.secretPasswordKey" . }} + {{- end }} + {{- else }} + - name: ALLOW_EMPTY_PASSWORD + value: "yes" + {{- end }} + ports: + - name: redis + containerPort: {{ .Values.redisPort }} + {{- if .Values.slave.livenessProbe.enabled }} + livenessProbe: + initialDelaySeconds: {{ .Values.slave.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.slave.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.slave.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.slave.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.slave.livenessProbe.failureThreshold}} + exec: + command: + - sh + - -c + {{- if .Values.sentinel.enabled }} + - /health/ping_liveness_local.sh {{ .Values.slave.livenessProbe.timeoutSeconds }} + {{- else }} + - /health/ping_liveness_local_and_master.sh {{ .Values.slave.livenessProbe.timeoutSeconds }} + {{- end }} + {{- end }} + + {{- if .Values.slave.readinessProbe.enabled }} + readinessProbe: + initialDelaySeconds: {{ .Values.slave.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.slave.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.slave.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.slave.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.slave.readinessProbe.failureThreshold }} + exec: + command: + - sh + - -c + {{- if .Values.sentinel.enabled }} + - /health/ping_readiness_local.sh {{ .Values.slave.livenessProbe.timeoutSeconds }} + {{- else }} + - /health/ping_readiness_local_and_master.sh {{ .Values.slave.livenessProbe.timeoutSeconds }} + {{- end }} + {{- end }} + resources: +{{ toYaml .Values.slave.resources | indent 10 }} + volumeMounts: + - name: health + mountPath: /health + {{- if .Values.usePasswordFile }} + - name: redis-password + mountPath: /opt/bitnami/redis/secrets/ + {{- end }} + - name: redis-data + mountPath: /data + - name: config + mountPath: /opt/bitnami/redis/mounted-etc + - name: redis-tmp-conf + mountPath: /opt/bitnami/redis/etc + {{- if and .Values.cluster.enabled .Values.sentinel.enabled }} + - name: sentinel + image: "{{ template "sentinel.image" . }}" + imagePullPolicy: {{ .Values.sentinel.image.pullPolicy | quote }} + {{- if .Values.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + command: + - /bin/bash + - -c + - | + if [[ -n $REDIS_PASSWORD_FILE ]]; then + password_aux=`cat ${REDIS_PASSWORD_FILE}` + export REDIS_PASSWORD=$password_aux + fi + if [[ ! -f /opt/bitnami/redis-sentinel/etc/sentinel.conf ]];then + cp /opt/bitnami/redis-sentinel/mounted-etc/sentinel.conf /opt/bitnami/redis-sentinel/etc/sentinel.conf + {{- if .Values.usePassword }} + printf "\nsentinel auth-pass {{ .Values.sentinel.masterSet }} $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf + {{- if .Values.sentinel.usePassword }} + printf "\nrequirepass $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf + {{- end }} + {{- end }} + {{- if .Values.sentinel.staticID }} + printf "\nsentinel myid $(echo $HOSTNAME | openssl sha1 | awk '{ print $2 }')" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf + {{- end }} + fi + + redis-server /opt/bitnami/redis-sentinel/etc/sentinel.conf --sentinel + env: + {{- if .Values.usePassword }} + {{- if .Values.usePasswordFile }} + - name: REDIS_PASSWORD_FILE + value: "/opt/bitnami/redis/secrets/redis-password" + {{- else }} + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "redis.secretName" . }} + key: {{ template "redis.secretPasswordKey" . }} + {{- end }} + {{- else }} + - name: ALLOW_EMPTY_PASSWORD + value: "yes" + {{- end }} + - name: REDIS_SENTINEL_PORT + value: {{ .Values.sentinel.port | quote }} + ports: + - name: redis-sentinel + containerPort: {{ .Values.sentinel.port }} + {{- if .Values.sentinel.livenessProbe.enabled }} + livenessProbe: + initialDelaySeconds: {{ .Values.sentinel.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.sentinel.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.sentinel.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.sentinel.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.sentinel.livenessProbe.failureThreshold }} + exec: + command: + - sh + - -c + - /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.sentinel.readinessProbe.enabled}} + readinessProbe: + initialDelaySeconds: {{ .Values.sentinel.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.sentinel.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.sentinel.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.sentinel.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.sentinel.readinessProbe.failureThreshold }} + exec: + command: + - sh + - -c + - /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }} + {{- end }} + resources: +{{ toYaml .Values.sentinel.resources | indent 10 }} + volumeMounts: + - name: health + mountPath: /health + {{- if .Values.usePasswordFile }} + - name: redis-password + mountPath: /opt/bitnami/redis/secrets/ + {{- end }} + - name: redis-data + mountPath: {{ .Values.master.persistence.path }} + subPath: {{ .Values.master.persistence.subPath }} + - name: config + mountPath: /opt/bitnami/redis-sentinel/mounted-etc + - name: sentinel-tmp-conf + mountPath: /opt/bitnami/redis-sentinel/etc + {{- end }} +{{- if .Values.metrics.enabled }} + - name: metrics + image: {{ template "redis.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + command: + - /bin/bash + - -c + - | + if [[ -f '/secrets/redis-password' ]]; then + export REDIS_PASSWORD=$(cat /secrets/redis-password) + fi + redis_exporter{{- range $key, $value := .Values.metrics.extraArgs }} --{{ $key }}={{ $value }}{{- end }} + env: + - name: REDIS_ALIAS + value: {{ template "redis.fullname" . }} + {{- if and .Values.usePassword (not .Values.usePasswordFile) }} + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "redis.secretName" . }} + key: {{ template "redis.secretPasswordKey" . }} + {{- end }} + volumeMounts: + {{- if .Values.usePasswordFile }} + - name: redis-password + mountPath: /secrets/ + {{- end }} + ports: + - name: metrics + containerPort: 9121 + resources: +{{ toYaml .Values.metrics.resources | indent 10 }} +{{- end }} + {{- $needsVolumePermissions := and .Values.volumePermissions.enabled (and .Values.slave.persistence.enabled .Values.securityContext.enabled) }} + {{- if or $needsVolumePermissions .Values.sysctlImage.enabled }} + initContainers: + {{- if $needsVolumePermissions }} + - name: volume-permissions + image: "{{ template "redis.volumePermissions.image" . }}" + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: ["/bin/chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }}", "{{ .Values.slave.persistence.path }}"] + securityContext: + runAsUser: 0 + resources: +{{ toYaml .Values.volumePermissions.resources | indent 10 }} + volumeMounts: + - name: redis-data + mountPath: {{ .Values.slave.persistence.path }} + subPath: {{ .Values.slave.persistence.subPath }} + {{- end }} + {{- if .Values.sysctlImage.enabled }} + - name: init-sysctl + image: {{ template "redis.sysctl.image" . }} + imagePullPolicy: {{ default "" .Values.sysctlImage.pullPolicy | quote }} + resources: +{{ toYaml .Values.sysctlImage.resources | indent 10 }} + {{- if .Values.sysctlImage.mountHostSys }} + volumeMounts: + - name: host-sys + mountPath: /host-sys + {{- end }} + command: +{{ toYaml .Values.sysctlImage.command | indent 10 }} + securityContext: + privileged: true + runAsUser: 0 + {{- end }} + {{- end }} + volumes: + - name: health + configMap: + name: {{ template "redis.fullname" . }}-health + defaultMode: 0755 + {{- if .Values.usePasswordFile }} + - name: redis-password + secret: + secretName: {{ template "redis.secretName" . }} + items: + - key: {{ template "redis.secretPasswordKey" . }} + path: redis-password + {{- end }} + - name: config + configMap: + name: {{ template "redis.fullname" . }} + {{- if .Values.sysctlImage.mountHostSys }} + - name: host-sys + hostPath: + path: /sys + {{- end }} + - name: sentinel-tmp-conf + emptyDir: {} + - name: redis-tmp-conf + emptyDir: {} + {{- if not .Values.slave.persistence.enabled }} + - name: redis-data + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: redis-data + labels: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: slave + spec: + accessModes: + {{- range .Values.slave.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.slave.persistence.size | quote }} + {{ include "redis.slave.storageClass" . }} + selector: + {{- if .Values.slave.persistence.matchLabels }} + matchLabels: +{{ toYaml .Values.slave.persistence.matchLabels | indent 12 }} + {{- end -}} + {{- if .Values.slave.persistence.matchExpressions }} + matchExpressions: +{{ toYaml .Values.slave.persistence.matchExpressions | indent 12 }} + {{- end -}} + {{- end }} + updateStrategy: + type: {{ .Values.slave.statefulset.updateStrategy }} + {{- if .Values.slave.statefulset.rollingUpdatePartition }} + {{- if (eq "Recreate" .Values.slave.statefulset.updateStrategy) }} + rollingUpdate: null + {{- else }} + rollingUpdate: + partition: {{ .Values.slave.statefulset.rollingUpdatePartition }} + {{- end }} + {{- end }} +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-slave-svc.yaml b/infra/charts/feast/charts/redis/templates/redis-slave-svc.yaml new file mode 100644 index 00000000000..052ecea174e --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/redis-slave-svc.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.cluster.enabled (not .Values.sentinel.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "redis.fullname" . }}-slave + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.slave.service.labels -}} + {{ toYaml .Values.slave.service.labels | nindent 4 }} + {{- end -}} +{{- if .Values.slave.service.annotations }} + annotations: +{{ toYaml .Values.slave.service.annotations | indent 4 }} +{{- end }} +spec: + type: {{ .Values.slave.service.type }} + {{- if and (eq .Values.slave.service.type "LoadBalancer") .Values.slave.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.slave.service.loadBalancerIP }} + {{- end }} + {{- if and (eq .Values.slave.service.type "LoadBalancer") .Values.slave.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- with .Values.slave.service.loadBalancerSourceRanges }} +{{ toYaml . | indent 4 }} +{{- end }} + {{- end }} + ports: + - name: redis + port: {{ .Values.slave.service.port }} + targetPort: redis + {{- if .Values.slave.service.nodePort }} + nodePort: {{ .Values.slave.service.nodePort }} + {{- end }} + selector: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} + role: slave +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-with-sentinel-svc.yaml b/infra/charts/feast/charts/redis/templates/redis-with-sentinel-svc.yaml new file mode 100644 index 00000000000..5017c222a23 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/redis-with-sentinel-svc.yaml @@ -0,0 +1,40 @@ +{{- if .Values.sentinel.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "redis.fullname" . }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.sentinel.service.labels }} + {{ toYaml .Values.sentinel.service.labels | nindent 4 }} + {{- end }} +{{- if .Values.sentinel.service.annotations }} + annotations: +{{ toYaml .Values.sentinel.service.annotations | indent 4 }} +{{- end }} +spec: + type: {{ .Values.sentinel.service.type }} + {{ if eq .Values.sentinel.service.type "LoadBalancer" -}} {{ if .Values.sentinel.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.sentinel.service.loadBalancerIP }} + {{ end -}} + {{- end -}} + ports: + - name: redis + port: {{ .Values.sentinel.service.redisPort }} + targetPort: redis + {{- if .Values.sentinel.service.redisNodePort }} + nodePort: {{ .Values.sentinel.service.redisNodePort }} + {{- end }} + - name: redis-sentinel + port: {{ .Values.sentinel.service.sentinelPort }} + targetPort: redis-sentinel + {{- if .Values.sentinel.service.sentinelNodePort }} + nodePort: {{ .Values.sentinel.service.sentinelNodePort }} + {{- end }} + selector: + app: {{ template "redis.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/secret.yaml b/infra/charts/feast/charts/redis/templates/secret.yaml new file mode 100644 index 00000000000..ead9c611a47 --- /dev/null +++ b/infra/charts/feast/charts/redis/templates/secret.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.usePassword (not .Values.existingSecret) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "redis.fullname" . }} + labels: + app: {{ template "redis.name" . }} + chart: {{ template "redis.chart" . }} + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +type: Opaque +data: + redis-password: {{ include "redis.password" . | b64enc | quote }} +{{- end -}} diff --git a/infra/charts/feast/charts/redis/values-production.yaml b/infra/charts/feast/charts/redis/values-production.yaml new file mode 100644 index 00000000000..cae2af1ef0c --- /dev/null +++ b/infra/charts/feast/charts/redis/values-production.yaml @@ -0,0 +1,630 @@ +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + redis: {} + +## Bitnami Redis image version +## ref: https://hub.docker.com/r/bitnami/redis/tags/ +## +image: + registry: docker.io + repository: bitnami/redis + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.7-debian-10-r32 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +## String to partially override redis.fullname template (will maintain the release name) +## +# nameOverride: + +## String to fully override redis.fullname template +## +# fullnameOverride: + +## Cluster settings +cluster: + enabled: true + slaveCount: 3 + +## Use redis sentinel in the redis pod. This will disable the master and slave services and +## create one redis service with ports to the sentinel and the redis instances +sentinel: + enabled: false + ## Require password authentication on the sentinel itself + ## ref: https://redis.io/topics/sentinel + usePassword: true + ## Bitnami Redis Sentintel image version + ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ + ## + image: + registry: docker.io + repository: bitnami/redis-sentinel + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.7-debian-10-r27 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + masterSet: mymaster + initialCheckTimeout: 5 + quorum: 2 + downAfterMilliseconds: 60000 + failoverTimeout: 18000 + parallelSyncs: 1 + port: 26379 + ## Additional Redis configuration for the sentinel nodes + ## ref: https://redis.io/topics/config + ## + configmap: + ## Enable or disable static sentinel IDs for each replicas + ## If disabled each sentinel will generate a random id at startup + ## If enabled, each replicas will have a constant ID on each start-up + ## + staticID: false + ## Configure extra options for Redis Sentinel liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + ## Redis Sentinel resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Redis Sentinel Service properties + service: + ## Redis Sentinel Service type + type: ClusterIP + sentinelPort: 26379 + redisPort: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # sentinelNodePort: + # redisNodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + labels: {} + loadBalancerIP: + +## Specifies the Kubernetes Cluster's Domain Name. +## +clusterDomain: cluster.local + +networkPolicy: + ## Specifies whether a NetworkPolicy should be created + ## + enabled: true + + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to the port Redis is listening + ## on. When true, Redis will accept connections from any source + ## (with the correct destination port). + ## + # allowExternal: true + + ## Allow connections from other namespacess. Just set label for namespace and set label for pods (optional). + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} + +serviceAccount: + ## Specifies whether a ServiceAccount should be created + ## + create: false + ## The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the fullname template + name: + +rbac: + ## Specifies whether RBAC resources should be created + ## + create: false + + role: + ## Rules to create. It follows the role specification + # rules: + # - apiGroups: + # - extensions + # resources: + # - podsecuritypolicies + # verbs: + # - use + # resourceNames: + # - gce.unprivileged + rules: [] + +## Redis pod Security Context +securityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + ## sysctl settings for master and slave pods + ## + ## Uncomment the setting below to increase the net.core.somaxconn value + ## + # sysctls: + # - name: net.core.somaxconn + # value: "10000" + +## Use password authentication +usePassword: true +## Redis password (both master and slave) +## Defaults to a random 10-character alphanumeric string if not set and usePassword is true +## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run +## +password: +## Use existing secret (ignores previous password) +# existingSecret: +## Password key to be retrieved from Redis secret +## +# existingSecretPasswordKey: + +## Mount secrets as files instead of environment variables +usePasswordFile: false + +## Persist data to a persistent volume (Redis Master) +persistence: {} + ## A manually managed Persistent Volume and Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + # existingClaim: + +# Redis port +redisPort: 6379 + +## +## Redis Master parameters +## +master: + ## Redis command arguments + ## + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Additional Redis configuration for the master nodes + ## ref: https://redis.io/topics/config + ## + configmap: + ## Redis additional command line flags + ## + ## Can be used to specify command line flags, for example: + ## + ## extraFlags: + ## - "--maxmemory-policy volatile-ttl" + ## - "--repl-backlog-size 1024mb" + extraFlags: [] + ## Comma-separated list of Redis commands to disable + ## + ## Can be used to disable Redis commands for security reasons. + ## Commands will be completely disabled by renaming each to an empty string. + ## ref: https://redis.io/topics/security#disabling-of-specific-commands + ## + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Master additional pod labels and annotations + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + podAnnotations: {} + + ## Redis Master resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Configure extra options for Redis Master liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + + ## Redis Master Node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + ## Redis Master pod/node affinity/anti-affinity + ## + affinity: {} + + ## Redis Master Service properties + service: + ## Redis Master Service type + type: ClusterIP + port: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + labels: {} + loadBalancerIP: + # loadBalancerSourceRanges: ["10.0.0.0/8"] + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + ## Persistent Volume selectors + ## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector + matchLabels: {} + matchExpressions: {} + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + + ## Redis Master pod priorityClassName + # priorityClassName: {} + +## +## Redis Slave properties +## Note: service.type is a mandatory parameter +## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master +## +slave: + ## Slave Service properties + service: + ## Redis Slave Service type + type: ClusterIP + ## Redis port + port: 6379 + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + labels: {} + loadBalancerIP: + # loadBalancerSourceRanges: ["10.0.0.0/8"] + + ## Redis slave port + port: 6379 + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Additional Redis configuration for the slave nodes + ## ref: https://redis.io/topics/config + ## + configmap: + ## Redis extra flags + extraFlags: [] + ## List of Redis commands to disable + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Slave pod/node affinity/anti-affinity + ## + affinity: {} + + ## Configure extra options for Redis Slave liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 5 + + ## Redis slave Resource + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + + ## Redis slave selectors and tolerations for pod assignment + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Redis slave pod Annotation and Labels + podLabels: {} + podAnnotations: {} + + ## Redis slave pod priorityClassName + # priorityClassName: {} + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + ## Persistent Volume selectors + ## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector + matchLabels: {} + matchExpressions: {} + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + +## Prometheus Exporter / Metrics +## +metrics: + enabled: true + + image: + registry: docker.io + repository: bitnami/redis-exporter + tag: 1.4.0-debian-10-r3 + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + + ## Metrics exporter resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + # resources: {} + + ## Extra arguments for Metrics exporter, for example: + ## extraArgs: + ## check-keys: myKey,myOtherKey + # extraArgs: {} + + ## Metrics exporter pod Annotation and Labels + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9121" + # podLabels: {} + + # Enable this if you're using https://github.com/coreos/prometheus-operator + serviceMonitor: + enabled: false + ## Specify a namespace if needed + # namespace: monitoring + # fallback to the prometheus default unless specified + # interval: 10s + ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) + ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) + ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) + selector: + prometheus: kube-prometheus + + ## Metrics exporter pod priorityClassName + # priorityClassName: {} + service: + type: ClusterIP + ## Use serviceLoadBalancerIP to request a specific static IP, + ## otherwise leave blank + # loadBalancerIP: + annotations: {} + labels: {} + + ## Custom PrometheusRule to be defined + ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + prometheusRule: + enabled: false + additionalLabels: {} + namespace: "" + rules: [] + ## These are just examples rules, please adapt them to your needs. + ## Make sure to constraint the rules to the current postgresql service. + # - alert: RedisDown + # expr: redis_up{service="{{ template "redis.fullname" . }}-metrics"} == 0 + # for: 2m + # labels: + # severity: error + # annotations: + # summary: Redis instance {{ "{{ $instance }}" }} down + # description: Redis instance {{ "{{ $instance }}" }} is down. + # - alert: RedisMemoryHigh + # expr: > + # redis_memory_used_bytes{service="{{ template "redis.fullname" . }}-metrics"} * 100 + # / + # redis_memory_max_bytes{service="{{ template "redis.fullname" . }}-metrics"} + # > 90 =< 100 + # for: 2m + # labels: + # severity: error + # annotations: + # summary: Redis instance {{ "{{ $instance }}" }} is using too much memory + # description: Redis instance {{ "{{ $instance }}" }} is using {{ "{{ $value }}" }}% of its available memory. + # - alert: RedisKeyEviction + # expr: increase(redis_evicted_keys_total{service="{{ template "redis.fullname" . }}-metrics"}[5m]) > 0 + # for: 1s + # labels: + # severity: error + # annotations: + # summary: Redis instance {{ "{{ $instance }}" }} has evicted keys + # description: Redis instance {{ "{{ $instance }}" }} has evicted {{ "{{ $value }}" }} keys in the last 5 minutes. + +## +## Init containers parameters: +## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup +## +volumePermissions: + enabled: false + image: + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + +## Redis config file +## ref: https://redis.io/topics/config +## +configmap: |- + # Enable AOF https://redis.io/topics/persistence#append-only-file + appendonly yes + # Disable RDB persistence, AOF persistence already enabled. + save "" + +## Sysctl InitContainer +## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) +sysctlImage: + enabled: false + command: [] + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + mountHostSys: false + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + +## PodSecurityPolicy configuration +## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## +podSecurityPolicy: + ## Specifies whether a PodSecurityPolicy should be created + ## + create: false diff --git a/infra/charts/feast/charts/redis/values.schema.json b/infra/charts/feast/charts/redis/values.schema.json new file mode 100644 index 00000000000..2138e451e42 --- /dev/null +++ b/infra/charts/feast/charts/redis/values.schema.json @@ -0,0 +1,168 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "usePassword": { + "type": "boolean", + "title": "Use password authentication", + "form": true + }, + "password": { + "type": "string", + "title": "Password", + "form": true, + "description": "Defaults to a random 10-character alphanumeric string if not set", + "hidden": { + "condition": false, + "value": "usePassword" + } + }, + "cluster": { + "type": "object", + "title": "Cluster Settings", + "form": true, + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable master-slave", + "description": "Enable master-slave architecture" + }, + "slaveCount": { + "type": "integer", + "title": "Slave Replicas", + "form": true, + "hidden": { + "condition": false, + "value": "cluster.enabled" + } + } + } + }, + "master": { + "type": "object", + "title": "Master replicas settings", + "form": true, + "properties": { + "persistence": { + "type": "object", + "title": "Persistence for master replicas", + "form": true, + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable persistence", + "description": "Enable persistence using Persistent Volume Claims" + }, + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi", + "hidden": { + "condition": false, + "value": "master.persistence.enabled" + } + }, + "matchLabels": { + "type": "object", + "title": "Persistent Match Labels Selector" + }, + "matchExpressions": { + "type": "object", + "title": "Persistent Match Expressions Selector" + } + } + } + } + }, + "slave": { + "type": "object", + "title": "Slave replicas settings", + "form": true, + "hidden": { + "condition": false, + "value": "cluster.enabled" + }, + "properties": { + "persistence": { + "type": "object", + "title": "Persistence for slave replicas", + "form": true, + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable persistence", + "description": "Enable persistence using Persistent Volume Claims" + }, + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi", + "hidden": { + "condition": false, + "value": "slave.persistence.enabled" + } + }, + "matchLabels": { + "type": "object", + "title": "Persistent Match Labels Selector" + }, + "matchExpressions": { + "type": "object", + "title": "Persistent Match Expressions Selector" + } + } + } + } + }, + "volumePermissions": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable Init Containers", + "description": "Use an init container to set required folder permissions on the data volume before mounting it in the final destination" + } + } + }, + "metrics": { + "type": "object", + "form": true, + "title": "Prometheus metrics details", + "properties": { + "enabled": { + "type": "boolean", + "title": "Create Prometheus metrics exporter", + "description": "Create a side-car container to expose Prometheus metrics", + "form": true + }, + "serviceMonitor": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "Create Prometheus Operator ServiceMonitor", + "description": "Create a ServiceMonitor to track metrics using Prometheus Operator", + "form": true, + "hidden": { + "condition": false, + "value": "metrics.enabled" + } + } + } + } + } + } + } +} diff --git a/infra/charts/feast/charts/redis/values.yaml b/infra/charts/feast/charts/redis/values.yaml new file mode 100644 index 00000000000..901c5a44f9c --- /dev/null +++ b/infra/charts/feast/charts/redis/values.yaml @@ -0,0 +1,631 @@ +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + redis: {} + +## Bitnami Redis image version +## ref: https://hub.docker.com/r/bitnami/redis/tags/ +## +image: + registry: docker.io + repository: bitnami/redis + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.7-debian-10-r32 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +## String to partially override redis.fullname template (will maintain the release name) +## +# nameOverride: + +## String to fully override redis.fullname template +## +# fullnameOverride: + +## Cluster settings +cluster: + enabled: false + slaveCount: 1 + +## Use redis sentinel in the redis pod. This will disable the master and slave services and +## create one redis service with ports to the sentinel and the redis instances +sentinel: + enabled: false + ## Require password authentication on the sentinel itself + ## ref: https://redis.io/topics/sentinel + usePassword: true + ## Bitnami Redis Sentintel image version + ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ + ## + image: + registry: docker.io + repository: bitnami/redis-sentinel + ## Bitnami Redis image tag + ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links + ## + tag: 5.0.7-debian-10-r27 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + masterSet: mymaster + initialCheckTimeout: 5 + quorum: 2 + downAfterMilliseconds: 60000 + failoverTimeout: 18000 + parallelSyncs: 1 + port: 26379 + ## Additional Redis configuration for the sentinel nodes + ## ref: https://redis.io/topics/config + ## + configmap: + ## Enable or disable static sentinel IDs for each replicas + ## If disabled each sentinel will generate a random id at startup + ## If enabled, each replicas will have a constant ID on each start-up + ## + staticID: false + ## Configure extra options for Redis Sentinel liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + ## Redis Sentinel resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Redis Sentinel Service properties + service: + ## Redis Sentinel Service type + type: ClusterIP + sentinelPort: 26379 + redisPort: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # sentinelNodePort: + # redisNodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + labels: {} + loadBalancerIP: + +## Specifies the Kubernetes Cluster's Domain Name. +## +clusterDomain: cluster.local + +networkPolicy: + ## Specifies whether a NetworkPolicy should be created + ## + enabled: false + + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to the port Redis is listening + ## on. When true, Redis will accept connections from any source + ## (with the correct destination port). + ## + # allowExternal: true + + ## Allow connections from other namespacess. Just set label for namespace and set label for pods (optional). + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} + +serviceAccount: + ## Specifies whether a ServiceAccount should be created + ## + create: false + ## The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the fullname template + name: + +rbac: + ## Specifies whether RBAC resources should be created + ## + create: false + + role: + ## Rules to create. It follows the role specification + # rules: + # - apiGroups: + # - extensions + # resources: + # - podsecuritypolicies + # verbs: + # - use + # resourceNames: + # - gce.unprivileged + rules: [] + +## Redis pod Security Context +securityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + ## sysctl settings for master and slave pods + ## + ## Uncomment the setting below to increase the net.core.somaxconn value + ## + # sysctls: + # - name: net.core.somaxconn + # value: "10000" + +## Use password authentication +usePassword: false +## Redis password (both master and slave) +## Defaults to a random 10-character alphanumeric string if not set and usePassword is true +## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run +## +password: "" +## Use existing secret (ignores previous password) +# existingSecret: +## Password key to be retrieved from Redis secret +## +# existingSecretPasswordKey: + +## Mount secrets as files instead of environment variables +usePasswordFile: false + +## Persist data to a persistent volume (Redis Master) +persistence: {} + ## A manually managed Persistent Volume and Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + # existingClaim: + +# Redis port +redisPort: 6379 + +## +## Redis Master parameters +## +master: + ## Redis command arguments + ## + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Additional Redis configuration for the master nodes + ## ref: https://redis.io/topics/config + ## + configmap: + ## Redis additional command line flags + ## + ## Can be used to specify command line flags, for example: + ## + ## extraFlags: + ## - "--maxmemory-policy volatile-ttl" + ## - "--repl-backlog-size 1024mb" + extraFlags: [] + ## Comma-separated list of Redis commands to disable + ## + ## Can be used to disable Redis commands for security reasons. + ## Commands will be completely disabled by renaming each to an empty string. + ## ref: https://redis.io/topics/security#disabling-of-specific-commands + ## + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Master additional pod labels and annotations + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + podAnnotations: {} + + ## Redis Master resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Configure extra options for Redis Master liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + + ## Redis Master Node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + ## + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + ## Redis Master pod/node affinity/anti-affinity + ## + affinity: {} + + ## Redis Master Service properties + service: + ## Redis Master Service type + type: ClusterIP + port: 6379 + + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + labels: {} + loadBalancerIP: + # loadBalancerSourceRanges: ["10.0.0.0/8"] + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + ## Persistent Volume selectors + ## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector + matchLabels: {} + matchExpressions: {} + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + + ## Redis Master pod priorityClassName + # priorityClassName: {} + +## +## Redis Slave properties +## Note: service.type is a mandatory parameter +## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master +## +slave: + ## Slave Service properties + service: + ## Redis Slave Service type + type: ClusterIP + ## Redis port + port: 6379 + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + labels: {} + loadBalancerIP: + # loadBalancerSourceRanges: ["10.0.0.0/8"] + + ## Redis slave port + port: 6379 + ## Can be used to specify command line arguments, for example: + ## + command: "/run.sh" + ## Additional Redis configuration for the slave nodes + ## ref: https://redis.io/topics/config + ## + configmap: + ## Redis extra flags + extraFlags: [] + ## List of Redis commands to disable + disableCommands: + - FLUSHDB + - FLUSHALL + + ## Redis Slave pod/node affinity/anti-affinity + ## + affinity: {} + + ## Configure extra options for Redis Slave liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 5 + + ## Redis slave Resource + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + + ## Redis slave selectors and tolerations for pod assignment + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} + # tolerations: [] + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## Redis slave pod Annotation and Labels + podLabels: {} + podAnnotations: {} + + ## Redis slave pod priorityClassName + # priorityClassName: {} + + ## Enable persistence using Persistent Volume Claims + ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + enabled: true + ## The path the volume will be mounted at, useful when using different + ## Redis images. + path: /data + ## The subdirectory of the volume to mount to, useful in dev environments + ## and one PV for multiple services. + subPath: "" + ## redis data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + accessModes: + - ReadWriteOnce + size: 8Gi + ## Persistent Volume selectors + ## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector + matchLabels: {} + matchExpressions: {} + + ## Update strategy, can be set to RollingUpdate or onDelete by default. + ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets + statefulset: + updateStrategy: RollingUpdate + ## Partition update strategy + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + # rollingUpdatePartition: + +## Prometheus Exporter / Metrics +## +metrics: + enabled: false + + image: + registry: docker.io + repository: bitnami/redis-exporter + tag: 1.4.0-debian-10-r3 + 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + + ## Metrics exporter resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + # resources: {} + + ## Extra arguments for Metrics exporter, for example: + ## extraArgs: + ## check-keys: myKey,myOtherKey + # extraArgs: {} + + ## Metrics exporter pod Annotation and Labels + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9121" + # podLabels: {} + + # Enable this if you're using https://github.com/coreos/prometheus-operator + serviceMonitor: + enabled: false + ## Specify a namespace if needed + # namespace: monitoring + # fallback to the prometheus default unless specified + # interval: 10s + ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) + ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) + ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) + selector: + prometheus: kube-prometheus + + ## Custom PrometheusRule to be defined + ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + prometheusRule: + enabled: false + additionalLabels: {} + namespace: "" + rules: [] + ## These are just examples rules, please adapt them to your needs. + ## Make sure to constraint the rules to the current postgresql service. + # - alert: RedisDown + # expr: redis_up{service="{{ template "redis.fullname" . }}-metrics"} == 0 + # for: 2m + # labels: + # severity: error + # annotations: + # summary: Redis instance {{ "{{ $instance }}" }} down + # description: Redis instance {{ "{{ $instance }}" }} is down. + # - alert: RedisMemoryHigh + # expr: > + # redis_memory_used_bytes{service="{{ template "redis.fullname" . }}-metrics"} * 100 + # / + # redis_memory_max_bytes{service="{{ template "redis.fullname" . }}-metrics"} + # > 90 =< 100 + # for: 2m + # labels: + # severity: error + # annotations: + # summary: Redis instance {{ "{{ $instance }}" }} is using too much memory + # description: Redis instance {{ "{{ $instance }}" }} is using {{ "{{ $value }}" }}% of its available memory. + # - alert: RedisKeyEviction + # expr: increase(redis_evicted_keys_total{service="{{ template "redis.fullname" . }}-metrics"}[5m]) > 0 + # for: 1s + # labels: + # severity: error + # annotations: + # summary: Redis instance {{ "{{ $instance }}" }} has evicted keys + # description: Redis instance {{ "{{ $instance }}" }} has evicted {{ "{{ $value }}" }} keys in the last 5 minutes. + + + ## Metrics exporter pod priorityClassName + # priorityClassName: {} + service: + type: ClusterIP + ## Use serviceLoadBalancerIP to request a specific static IP, + ## otherwise leave blank + # loadBalancerIP: + annotations: {} + labels: {} + +## +## Init containers parameters: +## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup +## +volumePermissions: + enabled: false + image: + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + +## Redis config file +## ref: https://redis.io/topics/config +## +configmap: |- + # Enable AOF https://redis.io/topics/persistence#append-only-file + appendonly yes + # Disable RDB persistence, AOF persistence already enabled. + save "" + +## Sysctl InitContainer +## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) +sysctlImage: + enabled: false + command: [] + registry: docker.io + repository: bitnami/minideb + tag: buster + pullPolicy: Always + ## 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/ + ## + # pullSecrets: + # - myRegistryKeySecretName + mountHostSys: false + resources: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + +## PodSecurityPolicy configuration +## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## +podSecurityPolicy: + ## Specifies whether a PodSecurityPolicy should be created + ## + create: false diff --git a/infra/charts/feast/files/img/dataflow-jobs.png b/infra/charts/feast/files/img/dataflow-jobs.png new file mode 100644 index 0000000000000000000000000000000000000000..2acf48f19e9611d9288654216e0194ca02f0df63 GIT binary patch literal 29728 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 Ho4EfM?6XoL literal 0 HcmV?d00001 diff --git a/infra/charts/feast/files/img/prometheus-server.png b/infra/charts/feast/files/img/prometheus-server.png new file mode 100644 index 0000000000000000000000000000000000000000..efe31dc9e1384db6ff12eb59e63e20e197e6d3c1 GIT binary patch literal 84787 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�c5h>hd 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 literal 0 HcmV?d00001 diff --git a/infra/charts/feast/requirements.lock b/infra/charts/feast/requirements.lock deleted file mode 100644 index e441790dc76..00000000000 --- a/infra/charts/feast/requirements.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: common - repository: https://kubernetes-charts-incubator.storage.googleapis.com - version: 0.0.5 -digest: sha256:935bfb09e9ed90ff800826a7df21adaabe3225511c3ad78df44e1a5a60e93f14 -generated: 2019-12-10T14:47:49.57569Z diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index 1fa1826965a..116acbd4543 100644 --- a/infra/charts/feast/requirements.yaml +++ b/infra/charts/feast/requirements.yaml @@ -1,12 +1,30 @@ dependencies: - name: feast-core - version: 0.4.4 + version: 0.4.6 condition: feast-core.enabled - name: feast-serving - alias: feast-serving-batch - version: 0.4.4 - condition: feast-serving-batch.enabled + alias: feast-online-serving + version: 0.4.6 + condition: feast-online-serving.enabled - name: feast-serving - alias: feast-serving-online - version: 0.4.4 - condition: feast-serving-online.enabled \ No newline at end of file + alias: feast-batch-serving + version: 0.4.6 + condition: feast-batch-serving.enabled +- name: postgresql + version: 8.6.1 + condition: postgresql.enabled +- name: kafka + version: 0.20.8 + condition: kafka.enabled +- name: redis + version: 10.5.6 + condition: redis.enabled +- name: prometheus-statsd-exporter + version: 0.1.2 + condition: prometheus-statsd-exporter.enabled +- name: prometheus + version: 11.0.2 + condition: prometheus.enabled +- name: grafana + version: 5.0.5 + condition: grafana.enabled diff --git a/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml b/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml new file mode 100644 index 00000000000..7c4f2075b9b --- /dev/null +++ b/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml @@ -0,0 +1,114 @@ +{{- if and (index .Values "feast-core" "enabled") (index .Values "feast-batch-serving" "enabled") }} + +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-feast-batch-serving-test" + annotations: + "helm.sh/hook": test-success + namespace: {{ .Release.Namespace }} +spec: + containers: + - name: main + image: python:3.7 + command: + - bash + - -c + - | + pip install -U feast==0.4.* + + cat < featureset.yaml + kind: feature_set + spec: + name: customer_transactions + entities: + - name: customer_id + valueType: INT64 + features: + - name: daily_transactions + valueType: FLOAT + - name: total_transactions + valueType: FLOAT + maxAge: 3600s + EOF + + python < featureset.yaml + kind: feature_set + spec: + name: customer_transactions + entities: + - name: customer_id + valueType: INT64 + features: + - name: daily_transactions + valueType: FLOAT + - name: total_transactions + valueType: FLOAT + maxAge: 3600s + EOF + + python < + dataset_id: + subscriptions: + - project: "*" + name: "*" + version: "*" + application-override.yaml: + feast: + jobs: + staging-location: gs:///staging-location + gcpServiceAccount: + enabled: true diff --git a/infra/charts/feast/values-dataflow-runner.yaml b/infra/charts/feast/values-dataflow-runner.yaml new file mode 100644 index 00000000000..a0cb477c6ff --- /dev/null +++ b/infra/charts/feast/values-dataflow-runner.yaml @@ -0,0 +1,100 @@ +feast-core: + gcpServiceAccount: + enabled: true + application-override.yaml: + feast: + stream: + options: + bootstrapServers: + jobs: + runner: DataflowRunner + options: + project: + region: + zone: + tempLocation: + network: + subnetwork: + maxNumWorkers: 1 + autoscalingAlgorithm: THROUGHPUT_BASED + usePublicIps: false + workerMachineType: n1-standard-1 + deadLetterTableSpec: + metrics: + host: + +feast-online-serving: + store.yaml: + name: redis-store + type: REDIS + redis_config: + host: + port: 6379 + subscriptions: + - project: "*" + name: "*" + version: "*" + +feast-batch-serving: + enabled: true + store.yaml: + name: bigquery-store + type: BIGQUERY + bigquery_config: + project_id: + dataset_id: + subscriptions: + - project: "*" + name: "*" + version: "*" + application-override.yaml: + feast: + jobs: + staging-location: + gcpServiceAccount: + enabled: true + +kafka: + external: + enabled: true + type: LoadBalancer + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + firstListenerPort: 31090 + loadBalancerIP: + - + - + - + configurationOverrides: + "advertised.listeners": |- + EXTERNAL://${LOAD_BALANCER_IP}:31090 + "listener.security.protocol.map": |- + PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT + "log.retention.hours": 1 + +redis: + master: + service: + type: LoadBalancer + loadBalancerIP: + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + +prometheus-statsd-exporter: + service: + type: LoadBalancer + annotations: + cloud.google.com/load-balancer-type: Internal + loadBalancerSourceRanges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + loadBalancerIP: diff --git a/infra/charts/feast/values-demo.yaml b/infra/charts/feast/values-demo.yaml deleted file mode 100644 index 2cb5ccbe741..00000000000 --- a/infra/charts/feast/values-demo.yaml +++ /dev/null @@ -1,84 +0,0 @@ -# The following are values for installing Feast for demonstration purpose: -# - Persistence is disabled since for demo purpose data is not expected -# to be durable -# - Only online serving (no batch serving) is installed to remove dependency -# on Google Cloud services. Batch serving requires BigQuery dependency. -# - Replace all occurrences of "feast.example.com" with the domain name or -# external IP pointing to your cluster -# - -feast-core: - enabled: true - - gcpServiceAccount: - useExistingSecret: false - - service: - type: NodePort - grpc: - nodePort: 32090 - - - resources: - requests: - cpu: 250m - memory: 256Mi - - postgresql: - persistence: - enabled: false - - - kafka: - enabled: true - persistence: - enabled: false - external: - enabled: true - type: NodePort - domain: feast.example.com - configurationOverrides: - "advertised.listeners": |- - EXTERNAL://feast.example.com:$((31090 + ${KAFKA_BROKER_ID})) - "listener.security.protocol.map": |- - PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT - - application.yaml: - feast: - stream: - options: - bootstrapServers: feast.example.com:31090 - -feast-serving-online: - enabled: true - redis: - enabled: true - - service: - type: NodePort - grpc: - nodePort: 32091 - - store.yaml: - name: redis - type: REDIS - subscriptions: - - name: "*" - project: "*" - version: "*" - -feast-serving-batch: -# enabled: false - enabled: true - store.yaml: - name: bigquery - type: BIGQUERY - bigquery_config: - project_id: PROJECT_ID - dataset_id: DATASET_ID - subscriptions: - - project: "*" - name: "*" - version: "*" - redis: - enabled: false \ No newline at end of file diff --git a/infra/charts/feast/values-existing-secret.yaml b/infra/charts/feast/values-existing-secret.yaml new file mode 100644 index 00000000000..0cccf004db9 --- /dev/null +++ b/infra/charts/feast/values-existing-secret.yaml @@ -0,0 +1,10 @@ +feast-core: + postgresql: + existingSecret: feast-postgresql + +postgresql: + existingSecret: feast-postgresql + +grafana: + admin: + existingSecret: feast-grafana diff --git a/infra/charts/feast/values-external-store.yaml b/infra/charts/feast/values-external-store.yaml deleted file mode 100644 index d012bcec56c..00000000000 --- a/infra/charts/feast/values-external-store.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# TODO @dheryanto -# -# The following are sample values for installing Feast without setting up -# Kafka and Redis stores. In other words, using Feast with external stream -# source and stores. diff --git a/infra/charts/feast/values-production.yaml b/infra/charts/feast/values-production.yaml deleted file mode 100644 index 6b53dc19ea8..00000000000 --- a/infra/charts/feast/values-production.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# TODO @dheryanto -# -# The following are sample values for installing Feast for typical production -# environment. diff --git a/infra/charts/feast/values.yaml b/infra/charts/feast/values.yaml index fde03f9ad71..20ee2ab029f 100644 --- a/infra/charts/feast/values.yaml +++ b/infra/charts/feast/values.yaml @@ -1,262 +1,35 @@ -# Feast deployment installs the following components: -# - Feast Core -# - Feast Serving Online -# - Feast Serving Batch -# - Prometheus StatsD Exporter -# -# The configuration for different components can be referenced from: -# - charts/feast-core/values.yaml -# - charts/feast-serving/values.yaml -# - charts/prometheus-statsd-exporter/values.yaml -# -# Note that "feast-serving-online" and "feast-serving-batch" are -# aliases to "feast-serving" chart since in typical scenario two instances -# of Feast Serving: online and batch will be deployed. Both described -# using the same chart "feast-serving". -# -# Note that the import job by default uses DirectRunner -# https://beam.apache.org/documentation/runners/direct/ -# in this configuration since it allows Feast to run in more environments -# (unlike DataflowRunner which requires Google Cloud services). -# -# A secret containing Google Cloud service account JSON key is required -# in this configuration. -# https://cloud.google.com/iam/docs/creating-managing-service-accounts -# -# The Google Cloud service account must have the following roles: -# - bigquery.dataEditor -# - bigquery.jobUser -# -# Assuming a service account JSON key file has been downloaded to -# (please name the file key.json): -# /home/user/key.json -# -# Run the following command to create the secret in your Kubernetes cluster: -# -# kubectl create secret generic feast-gcp-service-account \ -# --from-file=/home/user/key.json -# -# Replace every instance of EXTERNAL_IP with the external IP of your GKE cluster - -# ============================================================ -# Feast Core -# ============================================================ - feast-core: - # If enabled specifies whether to install Feast Core component. - # - # Normally, this is set to "false" when Feast users need access to low latency - # Feast Serving, by deploying multiple instances of Feast Serving closest - # to the client. These instances of Feast Serving however can still use - # the same shared Feast Core. + # feast-core.enabled -- Flag to install Feast Core enabled: true - # Specify which image tag to use. Keep this consistent for all components - image: - tag: "0.4.4" +feast-online-serving: + # feast-online-serving.enabled -- Flag to install Feast Online Serving + enabled: true - # jvmOptions are options that will be passed to the Java Virtual Machine (JVM) - # running Feast Core. - # - # For example, it is good practice to set min and max heap size in JVM. - # https://stackoverflow.com/questions/6902135/side-effect-for-increasing-maxpermsize-and-max-heap-size - jvmOptions: - - -Xms1024m - - -Xmx1024m +feast-batch-serving: + # feast-batch-serving.enabled -- Flag to install Feast Batch Serving + enabled: false - # resources that should be allocated to Feast Core. - resources: - requests: - cpu: 1000m - memory: 1024Mi - limits: - memory: 2048Mi +postgresql: + # postgresql.enabled -- Flag to install Postgresql + enabled: true - # gcpServiceAccount is the Google service account that Feast Core will use. - gcpServiceAccount: - # useExistingSecret specifies Feast to use an existing secret containing - # Google Cloud service account JSON key file. - # - # This is the only supported option for now to use a service account JSON. - # Feast admin is expected to create this secret before deploying Feast. - useExistingSecret: true - existingSecret: - # name is the secret name of the existing secret for the service account. - name: feast-gcp-service-account - # key is the secret key of the existing secret for the service account. - # key is normally derived from the file name of the JSON key file. - key: key.json - # Setting service.type to NodePort exposes feast-core service at a static port - service: - type: NodePort - grpc: - # this is the port that is exposed outside of the cluster - nodePort: 32090 - # Make kafka externally accessible using NodePort - # Please set EXTERNAL_IP to your cluster's external IP - kafka: - external: - enabled: true - type: NodePort - domain: EXTERNAL_IP - configurationOverrides: - "advertised.listeners": |- - EXTERNAL://EXTERNAL_IP:$((31090 + ${KAFKA_BROKER_ID})) - "listener.security.protocol.map": |- - PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT - application.yaml: - feast: - stream: - options: - # Point to one of your Kafka brokers - # Please set EXTERNAL_IP to your cluster's external IP - bootstrapServers: EXTERNAL_IP:31090 +kafka: + # kafka.enabled -- Flag to install Kafka + enabled: true -# ============================================================ -# Feast Serving Online -# ============================================================ +redis: + # redis.enabled -- Flag to install Redis + enabled: true -feast-serving-online: - # enabled specifies whether to install Feast Serving Online component. +prometheus-statsd-exporter: + # prometheus-statsd-exporter.enabled -- Flag to install StatsD to Prometheus Exporter enabled: true - # Specify what image tag to use. Keep this consistent for all components - image: - tag: "0.4.4" - # redis.enabled specifies whether Redis should be installed as part of Feast Serving. - # - # If enabled is set to "false", Feast admin has to ensure there is an - # existing Redis running outside Feast, that Feast Serving can connect to. - # master.service.type set to NodePort exposes Redis to outside of the cluster - redis: - enabled: true - master: - service: - nodePort: 32101 - type: NodePort - # jvmOptions are options that will be passed to the Feast Serving JVM. - jvmOptions: - - -Xms1024m - - -Xmx1024m - # resources that should be allocated to Feast Serving. - resources: - requests: - cpu: 500m - memory: 1024Mi - limits: - memory: 2048Mi - # Make service accessible to outside of cluster using NodePort - service: - type: NodePort - grpc: - nodePort: 32091 - # store.yaml is the configuration for Feast Store. - # - # Refer to this link for more description: - # https://github.com/gojek/feast/blob/79eb4ab5fa3d37102c1dca9968162a98690526ba/protos/feast/core/Store.proto - store.yaml: - name: redis - type: REDIS - redis_config: - # If redis.enabled is set to false, Feast admin should uncomment and - # set the host value to an "existing" Redis instance Feast will use as - # online Store. Also use the correct port for that existing instance. - # - # Else, if redis.enabled is set to true, replace EXTERNAL_IP with your - # cluster's external IP. - # host: redis-host - host: EXTERNAL_IP - port: 32101 - subscriptions: - - name: "*" - project: "*" - version: "*" -# ============================================================ -# Feast Serving Batch -# ============================================================ +prometheus: + # prometheus.enabled -- Flag to install Prometheus + enabled: true -feast-serving-batch: - # enabled specifies whether to install Feast Serving Batch component. +grafana: + # grafana.enabled -- Flag to install Grafana enabled: true - # Specify what image tag to use. Keep this consistent for all components - image: - tag: "0.4.4" - # redis.enabled specifies whether Redis should be installed as part of Feast Serving. - # - # This is usually set to "false" for Feast Serving Batch because the default - # store is BigQuery. - redis: - enabled: false - # jvmOptions are options that will be passed to the Feast Serving JVM. - jvmOptions: - - -Xms1024m - - -Xmx1024m - # resources that should be allocated to Feast Serving. - resources: - requests: - cpu: 500m - memory: 1024Mi - limits: - memory: 2048Mi - # Make service accessible to outside of cluster using NodePort - service: - type: NodePort - grpc: - nodePort: 32092 - # gcpServiceAccount is the service account that Feast Serving will use. - gcpServiceAccount: - # useExistingSecret specifies Feast to use an existing secret containing - # Google Cloud service account JSON key file. - # - # This is the only supported option for now to use a service account JSON. - # Feast admin is expected to create this secret before deploying Feast. - useExistingSecret: true - existingSecret: - # name is the secret name of the existing secret for the service account. - name: feast-gcp-service-account - # key is the secret key of the existing secret for the service account. - # key is normally derived from the file name of the JSON key file. - key: key.json - # application.yaml is the main configuration for Feast Serving application. - # - # Feast Core is a Spring Boot app which uses this yaml configuration file. - # Refer to https://github.com/gojek/feast/blob/79eb4ab5fa3d37102c1dca9968162a98690526ba/serving/src/main/resources/application.yml - # for a complete list and description of the configuration. - application.yaml: - feast: - jobs: - # staging-location specifies the URI to store intermediate files for - # batch serving (required if using BigQuery as Store). - # - # Please set the value to an "existing" Google Cloud Storage URI that - # Feast serving has write access to. - staging-location: gs://YOUR_BUCKET_NAME/serving/batch - # Type of store to store job metadata. - # - # This default configuration assumes that Feast Serving Online is - # enabled as well. So Feast Serving Batch will share the same - # Redis instance to store job statuses. - store-type: REDIS - # Default to use the internal hostname of the redis instance deployed by Online service, - # otherwise use externally exposed by setting EXTERNAL_IP to your cluster's external IP - # store-options: - # host: EXTERNAL_IP - # port: 32101 - # store.yaml is the configuration for Feast Store. - # - # Refer to this link for more description: - # https://github.com/gojek/feast/blob/79eb4ab5fa3d37102c1dca9968162a98690526ba/protos/feast/core/Store.proto - store.yaml: - name: bigquery - type: BIGQUERY - bigquery_config: - # project_id specifies the Google Cloud Project. Please set this to the - # project id you are using BigQuery in. - project_id: PROJECT_ID - # dataset_id specifies an "existing" BigQuery dataset Feast Serving Batch - # will use. Please ensure this dataset is created beforehand. - dataset_id: DATASET_ID - subscriptions: - - name: "*" - project: "*" - version: "*" From cf26d16ca72a1e30e54099126bb88d25235c2949 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Fri, 13 Mar 2020 09:23:12 +0800 Subject: [PATCH 02/15] Update docs --- infra/charts/feast/README.md | 7 +- infra/charts/feast/README.md.gotmpl | 7 +- infra/charts/feast/charts/grafana/README.md | 449 ++++++--- infra/charts/feast/charts/kafka/README.md | 546 ++++++++--- .../charts/feast/charts/postgresql/README.md | 700 ++++++++++--- .../prometheus-statsd-exporter/README.md | 106 +- .../charts/feast/charts/prometheus/README.md | 919 +++++++++--------- infra/charts/feast/charts/redis/README.md | 666 +++++++++---- 8 files changed, 2350 insertions(+), 1050 deletions(-) diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 36f19730308..1b3f5746727 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -22,10 +22,9 @@ This chart install Feast deployment on a Kubernetes cluster using the [Helm](htt ## Chart requirements -The chart dependencies are bundled in this chart so Feast users do need to run -`helm dep update` to update the dependencies. It also allows Feast chart -maintainers to set reasonable defaults values for the dependencies so end users -of Feast are not overwhelmed with the available configuration. +The chart dependencies are bundled in this chart so Feast users can use them directly. +It also allows Feast chart maintainers to set reasonable defaults values for the +dependencies so end users are not overwhelmed with the available configuration. | Name | Version | |------|---------| diff --git a/infra/charts/feast/README.md.gotmpl b/infra/charts/feast/README.md.gotmpl index 2c6c4e03b50..269b0517006 100644 --- a/infra/charts/feast/README.md.gotmpl +++ b/infra/charts/feast/README.md.gotmpl @@ -21,10 +21,9 @@ This chart install Feast deployment on a Kubernetes cluster using the [Helm](htt ## Chart requirements -The chart dependencies are bundled in this chart so Feast users do need to run -`helm dep update` to update the dependencies. It also allows Feast chart -maintainers to set reasonable defaults values for the dependencies so end users -of Feast are not overwhelmed with the available configuration. +The chart dependencies are bundled in this chart so Feast users can use them directly. +It also allows Feast chart maintainers to set reasonable defaults values for the +dependencies so end users are not overwhelmed with the available configuration. | Name | Version | |------|---------| diff --git a/infra/charts/feast/charts/grafana/README.md b/infra/charts/feast/charts/grafana/README.md index e50bb165d7b..5003f778f1a 100644 --- a/infra/charts/feast/charts/grafana/README.md +++ b/infra/charts/feast/charts/grafana/README.md @@ -1,128 +1,321 @@ -grafana -======= -The leading tool for querying and visualizing time series and metrics. - -Current chart version is `5.0.5` - -Source code can be found [here](https://grafana.net) - - - -## Chart Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| "grafana.ini".analytics.check_for_updates | bool | `true` | | -| "grafana.ini".grafana_net.url | string | `"https://grafana.net"` | | -| "grafana.ini".log.mode | string | `"console"` | | -| "grafana.ini".paths.data | string | `"/var/lib/grafana/data"` | | -| "grafana.ini".paths.logs | string | `"/var/log/grafana"` | | -| "grafana.ini".paths.plugins | string | `"/var/lib/grafana/plugins"` | | -| "grafana.ini".paths.provisioning | string | `"/etc/grafana/provisioning"` | | -| admin.existingSecret | string | `""` | | -| admin.passwordKey | string | `"admin-password"` | | -| admin.userKey | string | `"admin-user"` | | -| adminUser | string | `"admin"` | | -| affinity | object | `{}` | | -| dashboardProviders | object | `{}` | | -| dashboards | object | `{}` | | -| dashboardsConfigMaps | object | `{}` | | -| datasources | object | `{}` | | -| deploymentStrategy.type | string | `"RollingUpdate"` | | -| downloadDashboards.env | object | `{}` | | -| downloadDashboardsImage.pullPolicy | string | `"IfNotPresent"` | | -| downloadDashboardsImage.repository | string | `"curlimages/curl"` | | -| downloadDashboardsImage.tag | string | `"7.68.0"` | | -| env | object | `{}` | | -| envFromSecret | string | `""` | | -| envRenderSecret | object | `{}` | | -| envValueFrom | object | `{}` | | -| extraConfigmapMounts | list | `[]` | | -| extraContainers | string | `""` | | -| extraEmptyDirMounts | list | `[]` | | -| extraInitContainers | list | `[]` | | -| extraSecretMounts | list | `[]` | | -| extraVolumeMounts | list | `[]` | | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.repository | string | `"grafana/grafana"` | | -| image.tag | string | `"6.6.2"` | | -| ingress.annotations | object | `{}` | | -| ingress.enabled | bool | `false` | | -| ingress.extraPaths | list | `[]` | | -| ingress.hosts[0] | string | `"chart-example.local"` | | -| ingress.labels | object | `{}` | | -| ingress.path | string | `"/"` | | -| ingress.tls | list | `[]` | | -| initChownData.enabled | bool | `true` | | -| initChownData.image.pullPolicy | string | `"IfNotPresent"` | | -| initChownData.image.repository | string | `"busybox"` | | -| initChownData.image.tag | string | `"1.31.1"` | | -| initChownData.resources | object | `{}` | | -| ldap.config | string | `""` | | -| ldap.enabled | bool | `false` | | -| ldap.existingSecret | string | `""` | | -| livenessProbe.failureThreshold | int | `10` | | -| livenessProbe.httpGet.path | string | `"/api/health"` | | -| livenessProbe.httpGet.port | int | `3000` | | -| livenessProbe.initialDelaySeconds | int | `60` | | -| livenessProbe.timeoutSeconds | int | `30` | | -| namespaceOverride | string | `""` | | -| nodeSelector | object | `{}` | | -| notifiers | object | `{}` | | -| persistence.accessModes[0] | string | `"ReadWriteOnce"` | | -| persistence.enabled | bool | `false` | | -| persistence.finalizers[0] | string | `"kubernetes.io/pvc-protection"` | | -| persistence.size | string | `"10Gi"` | | -| persistence.type | string | `"pvc"` | | -| plugins | list | `[]` | | -| podDisruptionBudget | object | `{}` | | -| podPortName | string | `"grafana"` | | -| rbac.create | bool | `true` | | -| rbac.extraClusterRoleRules | list | `[]` | | -| rbac.extraRoleRules | list | `[]` | | -| rbac.namespaced | bool | `false` | | -| rbac.pspEnabled | bool | `true` | | -| rbac.pspUseAppArmor | bool | `true` | | -| readinessProbe.httpGet.path | string | `"/api/health"` | | -| readinessProbe.httpGet.port | int | `3000` | | -| replicas | int | `1` | | -| resources | object | `{}` | | -| securityContext.fsGroup | int | `472` | | -| securityContext.runAsUser | int | `472` | | -| service.annotations | object | `{}` | | -| service.labels | object | `{}` | | -| service.port | int | `80` | | -| service.portName | string | `"service"` | | -| service.targetPort | int | `3000` | | -| service.type | string | `"ClusterIP"` | | -| serviceAccount.create | bool | `true` | | -| serviceAccount.name | string | `nil` | | -| serviceAccount.nameTest | string | `nil` | | -| sidecar.dashboards.SCProvider | bool | `true` | | -| sidecar.dashboards.defaultFolderName | string | `nil` | | -| sidecar.dashboards.enabled | bool | `false` | | -| sidecar.dashboards.folder | string | `"/tmp/dashboards"` | | -| sidecar.dashboards.label | string | `"grafana_dashboard"` | | -| sidecar.dashboards.provider.allowUiUpdates | bool | `false` | | -| sidecar.dashboards.provider.disableDelete | bool | `false` | | -| sidecar.dashboards.provider.folder | string | `""` | | -| sidecar.dashboards.provider.name | string | `"sidecarProvider"` | | -| sidecar.dashboards.provider.orgid | int | `1` | | -| sidecar.dashboards.provider.type | string | `"file"` | | -| sidecar.dashboards.searchNamespace | string | `nil` | | -| sidecar.dashboards.watchMethod | string | `"WATCH"` | | -| sidecar.datasources.enabled | bool | `false` | | -| sidecar.datasources.label | string | `"grafana_datasource"` | | -| sidecar.datasources.searchNamespace | string | `nil` | | -| sidecar.datasources.watchMethod | string | `"WATCH"` | | -| sidecar.image | string | `"kiwigrid/k8s-sidecar:0.1.99"` | | -| sidecar.imagePullPolicy | string | `"IfNotPresent"` | | -| sidecar.resources | object | `{}` | | -| smtp.existingSecret | string | `""` | | -| smtp.passwordKey | string | `"password"` | | -| smtp.userKey | string | `"user"` | | -| testFramework.enabled | bool | `true` | | -| testFramework.image | string | `"bats/bats"` | | -| testFramework.securityContext | object | `{}` | | -| testFramework.tag | string | `"v1.1.0"` | | -| tolerations | list | `[]` | | +# Grafana Helm Chart + +* Installs the web dashboarding system [Grafana](http://grafana.org/) + +## TL;DR; + +```console +$ helm install stable/grafana +``` + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm install --name my-release stable/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. + +## Configuration + +| Parameter | Description | Default | +|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| +| `replicas` | Number of nodes | `1` | +| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | +| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `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, "fsGroup": 472}` | +| `priorityClassName` | Name of Priority Class to assign pods | `nil` | +| `image.repository` | Image repository | `grafana/grafana` | +| `image.tag` | Image tag (`Must be >= 5.0.0`) | `6.6.2` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Image pull secrets | `{}` | +| `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.targetPort` | Internal service is port | `3000` | +| `service.nodePort` | Kubernetes service nodePort | `nil` | +| `service.annotations` | Service annotations | `{}` | +| `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) | `[]` | +| `serivce.externalIPs` | service external IP addresses | `[]` | +| `ingress.enabled` | Enables Ingress | `false` | +| `ingress.annotations` | Ingress annotations | `{}` | +| `ingress.labels` | Custom labels | `{}` | +| `ingress.path` | Ingress accepted path | `/` | +| `ingress.hosts` | Ingress accepted hostnames | `[]` | +| `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-alb-ingress-controller/guide/ingress/annotation/#actions). | `[]` | +| `ingress.tls` | Ingress TLS configuration | `[]` | +| `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 | `{}` | +| `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 | `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.subPath` | Mount a sub dir of the persistent volume | `nil` | +| `initChownData.enabled` | If false, don't reset data ownership at startup | true | +| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | +| `initChownData.image.tag` | init-chown-data container image tag | `latest` | +| `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. | `{}` | +| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment | `""` | +| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret | `{}` | +| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | +| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | +| `extraConfigmapMounts` | Additional grafana server configMap volume mounts | `[]` | +| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | +| `plugins` | Plugins to be loaded along with Grafana | `[]` | +| `datasources` | Configure grafana datasources (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 | `{}` | +| `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` | +| `sidecar.image` | Sidecar image | `kiwigrid/k8s-sidecar:0.1.99` | +| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | +| `sidecar.resources` | Sidecar resources | `{}` | +| `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.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.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.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` | If specified, the sidecar will search for dashboard 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 | `nil` | +| `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.searchNamespace` | If specified, the sidecar will search for datasources 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 | `nil` | +| `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. | `""` | +| `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.annotations` | ServiceAccount annotations | | +| `serviceAccount.create` | Create service account | `true` | +| `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` | `` | +| `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.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `true` | +| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `true` | +| `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` | +| `testFramework.enabled` | Whether to create test-related resources | `true` | +| `testFramework.image` | `test-framework` image repository. | `bats/bats` | +| `testFramework.tag` | `test-framework` image tag. | `v1.1.0` | +| `testFramework.securityContext` | `test-framework` securityContext | `{}` | +| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | +| `downloadDashboardsImage.repository` | Curl docker image repo | `curlimages/curl` | +| `downloadDashboardsImage.tag` | Curl docker image tag | `7.68.0` | +| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | +| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | + +### Example of extraVolumeMounts + +```yaml +- extraVolumeMounts: + - name: plugins + mountPath: /var/lib/grafana/plugins + subPath: configs/grafana/plugins + existingClaim: existing-grafana-claim + readOnly: false +``` + +## 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 + local-dashboard: + url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json +``` + +## BASE64 dashboards + +Dashboards could be storaged in 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: https://yourgerritserver/a/{project-name}/branches/{branch-id}/files/{file-id}/content where {project-name} and +{file-id} usualy 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 https://yourgerritserver/a/user%2Frepo/branches/master/files/dir1%2Fdir2%2Fdashboard/content + +## 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: +``` +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. The secrets must be created before `helm install` so +that the datasources init container can list the secrets. + +Secrets are recommended over configmaps for this usecase because datasources usually contain private +data like usernames and passwords. Secrets are the more appropriate cluster ressource to manage those. + +Example datasource config adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): +``` +apiVersion: v1 +kind: Secret +metadata: + name: sample-grafana-datasource + labels: + grafana_datasource: "1" +type: Opaque +stringData: + datasource.yaml: |- + # config file version + apiVersion: 1 + + # list of datasources that should be deleted from the database + deleteDatasources: + - name: Graphite + orgId: 1 + + # list of datasources to insert/update depending + # whats available in the database + 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 + +``` + diff --git a/infra/charts/feast/charts/kafka/README.md b/infra/charts/feast/charts/kafka/README.md index 6936f77a364..c9f3b9c4d86 100644 --- a/infra/charts/feast/charts/kafka/README.md +++ b/infra/charts/feast/charts/kafka/README.md @@ -1,114 +1,432 @@ -kafka -===== -Apache Kafka is publish-subscribe messaging rethought as a distributed commit log. - -Current chart version is `0.20.8` - -Source code can be found [here](https://kafka.apache.org/) - -## Chart Requirements - -| Repository | Name | Version | -|------------|------|---------| -| https://kubernetes-charts-incubator.storage.googleapis.com/ | zookeeper | 2.1.0 | - -## Chart Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| additionalPorts | object | `{}` | | -| affinity | object | `{}` | | -| configJob.backoffLimit | int | `6` | | -| configurationOverrides."confluent.support.metrics.enable" | bool | `false` | | -| envOverrides | object | `{}` | | -| external.distinct | bool | `false` | | -| external.dns.useExternal | bool | `true` | | -| external.dns.useInternal | bool | `false` | | -| external.domain | string | `"cluster.local"` | | -| external.enabled | bool | `false` | | -| external.firstListenerPort | int | `31090` | | -| external.init.image | string | `"lwolf/kubectl_deployer"` | | -| external.init.imagePullPolicy | string | `"IfNotPresent"` | | -| external.init.imageTag | string | `"0.4"` | | -| external.loadBalancerIP | list | `[]` | | -| external.loadBalancerSourceRanges | list | `[]` | | -| external.servicePort | int | `19092` | | -| external.type | string | `"NodePort"` | | -| headless.port | int | `9092` | | -| image | string | `"confluentinc/cp-kafka"` | | -| imagePullPolicy | string | `"IfNotPresent"` | | -| imageTag | string | `"5.0.1"` | | -| jmx.configMap.enabled | bool | `true` | | -| jmx.configMap.overrideConfig | object | `{}` | | -| jmx.configMap.overrideName | string | `""` | | -| jmx.port | int | `5555` | | -| jmx.whitelistObjectNames[0] | string | `"kafka.controller:*"` | | -| jmx.whitelistObjectNames[1] | string | `"kafka.server:*"` | | -| jmx.whitelistObjectNames[2] | string | `"java.lang:*"` | | -| jmx.whitelistObjectNames[3] | string | `"kafka.network:*"` | | -| jmx.whitelistObjectNames[4] | string | `"kafka.log:*"` | | -| kafkaHeapOptions | string | `"-Xmx1G -Xms1G"` | | -| logSubPath | string | `"logs"` | | -| nodeSelector | object | `{}` | | -| persistence.enabled | bool | `true` | | -| persistence.mountPath | string | `"/opt/kafka/data"` | | -| persistence.size | string | `"1Gi"` | | -| podAnnotations | object | `{}` | | -| podDisruptionBudget | object | `{}` | | -| podLabels | object | `{}` | | -| podManagementPolicy | string | `"OrderedReady"` | | -| prometheus.jmx.enabled | bool | `false` | | -| prometheus.jmx.image | string | `"solsson/kafka-prometheus-jmx-exporter@sha256"` | | -| prometheus.jmx.imageTag | string | `"a23062396cd5af1acdf76512632c20ea6be76885dfc20cd9ff40fb23846557e8"` | | -| prometheus.jmx.interval | string | `"10s"` | | -| prometheus.jmx.port | int | `5556` | | -| prometheus.jmx.resources | object | `{}` | | -| prometheus.jmx.scrapeTimeout | string | `"10s"` | | -| prometheus.kafka.affinity | object | `{}` | | -| prometheus.kafka.enabled | bool | `false` | | -| prometheus.kafka.image | string | `"danielqsj/kafka-exporter"` | | -| prometheus.kafka.imageTag | string | `"v1.2.0"` | | -| prometheus.kafka.interval | string | `"10s"` | | -| prometheus.kafka.nodeSelector | object | `{}` | | -| prometheus.kafka.port | int | `9308` | | -| prometheus.kafka.resources | object | `{}` | | -| prometheus.kafka.scrapeTimeout | string | `"10s"` | | -| prometheus.kafka.tolerations | list | `[]` | | -| prometheus.operator.enabled | bool | `false` | | -| prometheus.operator.prometheusRule.enabled | bool | `false` | | -| prometheus.operator.prometheusRule.namespace | string | `"monitoring"` | | -| prometheus.operator.prometheusRule.releaseNamespace | bool | `false` | | -| prometheus.operator.prometheusRule.rules[0].alert | string | `"KafkaNoActiveControllers"` | | -| prometheus.operator.prometheusRule.rules[0].annotations.message | string | `"The number of active controllers in {{ \"{{\" }} $labels.namespace {{ \"}}\" }} is less than 1. This usually means that some of the Kafka nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one whilst monitoring the under-replicated partitions graph)."` | | -| prometheus.operator.prometheusRule.rules[0].expr | string | `"max(kafka_controller_kafkacontroller_activecontrollercount_value) by (namespace) \u003c 1"` | | -| prometheus.operator.prometheusRule.rules[0].for | string | `"5m"` | | -| prometheus.operator.prometheusRule.rules[0].labels.severity | string | `"critical"` | | -| prometheus.operator.prometheusRule.rules[1].alert | string | `"KafkaMultipleActiveControllers"` | | -| prometheus.operator.prometheusRule.rules[1].annotations.message | string | `"The number of active controllers in {{ \"{{\" }} $labels.namespace {{ \"}}\" }} is greater than 1. This usually means that some of the Kafka nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one whilst monitoring the under-replicated partitions graph)."` | | -| prometheus.operator.prometheusRule.rules[1].expr | string | `"max(kafka_controller_kafkacontroller_activecontrollercount_value) by (namespace) \u003e 1"` | | -| prometheus.operator.prometheusRule.rules[1].for | string | `"5m"` | | -| prometheus.operator.prometheusRule.rules[1].labels.severity | string | `"critical"` | | -| prometheus.operator.prometheusRule.selector.prometheus | string | `"kube-prometheus"` | | -| prometheus.operator.serviceMonitor.namespace | string | `"monitoring"` | | -| prometheus.operator.serviceMonitor.releaseNamespace | bool | `false` | | -| prometheus.operator.serviceMonitor.selector.prometheus | string | `"kube-prometheus"` | | -| readinessProbe.failureThreshold | int | `3` | | -| readinessProbe.initialDelaySeconds | int | `30` | | -| readinessProbe.periodSeconds | int | `10` | | -| readinessProbe.successThreshold | int | `1` | | -| readinessProbe.timeoutSeconds | int | `5` | | -| replicas | int | `3` | | -| resources | object | `{}` | | -| securityContext | object | `{}` | | -| terminationGracePeriodSeconds | int | `60` | | -| tolerations | list | `[]` | | -| topics | list | `[]` | | -| updateStrategy.type | string | `"OnDelete"` | | -| zookeeper.affinity | object | `{}` | | -| zookeeper.enabled | bool | `true` | | -| zookeeper.env.ZK_HEAP_SIZE | string | `"1G"` | | -| zookeeper.image.PullPolicy | string | `"IfNotPresent"` | | -| zookeeper.persistence.enabled | bool | `false` | | -| zookeeper.port | int | `2181` | | -| zookeeper.resources | string | `nil` | | -| zookeeper.url | string | `""` | | +# Apache Kafka Helm Chart + +This is an implementation of Kafka StatefulSet found here: + + * https://github.com/Yolean/kubernetes-kafka + +## Pre Requisites: + +* Kubernetes 1.3 with alpha APIs enabled and support for storage classes + +* PV support on underlying infrastructure + +* Requires at least `v2.0.0-beta.1` version of helm to support + dependency management with requirements.yaml + +## StatefulSet Details + +* https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ + +## StatefulSet Caveats + +* https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#limitations + +## Chart Details + +This chart will do the following: + +* Implement a dynamically scalable kafka cluster using Kubernetes StatefulSets + +* Implement a dynamically scalable zookeeper cluster as another Kubernetes StatefulSet required for the Kafka cluster above + +* Expose Kafka protocol endpoints via NodePort services (optional) + +### Installing the Chart + +To install the chart with the release name `my-kafka` in the default +namespace: + +``` +$ helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator +$ helm install --name my-kafka incubator/kafka +``` + +If using a dedicated namespace(recommended) then make sure the namespace +exists with: + +``` +$ helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator +$ kubectl create ns kafka +$ helm install --name my-kafka --namespace kafka incubator/kafka +``` + +This chart includes a ZooKeeper chart as a dependency to the Kafka +cluster in its `requirement.yaml` by default. The chart can be customized using the +following configurable parameters: + +| Parameter | Description | Default | +|------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------| +| `image` | Kafka Container image name | `confluentinc/cp-kafka` | +| `imageTag` | Kafka Container image tag | `5.0.1` | +| `imagePullPolicy` | Kafka Container pull policy | `IfNotPresent` | +| `replicas` | Kafka Brokers | `3` | +| `component` | Kafka k8s selector key | `kafka` | +| `resources` | Kafka resource requests and limits | `{}` | +| `securityContext` | Kafka containers security context | `{}` | +| `kafkaHeapOptions` | Kafka broker JVM heap options | `-Xmx1G-Xms1G` | +| `logSubPath` | Subpath under `persistence.mountPath` where kafka logs will be placed. | `logs` | +| `schedulerName` | Name of Kubernetes scheduler (other than the default) | `nil` | +| `serviceAccountName` | Name of Kubernetes serviceAccount. Useful when needing to pull images from custom repositories | `nil` | +| `priorityClassName` | Name of Kubernetes Pod PriorityClass. https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass | `nil` | +| `affinity` | Defines affinities and anti-affinities for pods as defined in: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity preferences | `{}` | +| `tolerations` | List of node tolerations for the pods. https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | `[]` | +| `headless.annotations` | List of annotations for the headless service. https://kubernetes.io/docs/concepts/services-networking/service/#headless-services | `[]` | +| `headless.targetPort` | Target port to be used for the headless service. This is not a required value. | `nil` | +| `headless.port` | Port to be used for the headless service. https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | `9092` | +| `external.enabled` | If True, exposes Kafka brokers via NodePort (PLAINTEXT by default) | `false` | +| `external.dns.useInternal` | If True, add Annotation for internal DNS service | `false` | +| `external.dns.useExternal` | If True, add Annotation for external DNS service | `true` | +| `external.servicePort` | TCP port configured at external services (one per pod) to relay from NodePort to the external listener port. | '19092' | +| `external.firstListenerPort` | TCP port which is added pod index number to arrive at the port used for NodePort and external listener port. | '31090' | +| `external.domain` | Domain in which to advertise Kafka external listeners. | `cluster.local` | +| `external.type` | Service Type. | `NodePort` | +| `external.distinct` | Distinct DNS entries for each created A record. | `false` | +| `external.annotations` | Additional annotations for the external service. | `{}` | +| `external.loadBalancerIP` | Add Static IP to the type Load Balancer. Depends on the provider if enabled | `[]` +| `external.loadBalancerSourceRanges` | Add IP ranges that are allowed to access the Load Balancer. | `[]` +| `podAnnotations` | Annotation to be added to Kafka pods | `{}` | +| `podLabels` | Labels to be added to Kafka pods | `{}` | +| `podDisruptionBudget` | Define a Disruption Budget for the Kafka Pods | `{}` | +| `envOverrides` | Add additional Environment Variables in the dictionary format | `{ zookeeper.sasl.enabled: "False" }` | +| `configurationOverrides` | `Kafka ` [configuration setting][brokerconfigs] overrides in the dictionary format | `{ "confluent.support.metrics.enable": false }` | +| `secrets` | Pass any secrets to the kafka pods. Each secret will be passed as an environment variable by default. The secret can also be mounted to a specific path if required. Environment variable names are generated as: `_` (All upper case) | `{}` | +| `additionalPorts` | Additional ports to expose on brokers. Useful when the image exposes metrics (like prometheus, etc.) through a javaagent instead of a sidecar | `{}` | +| `readinessProbe.initialDelaySeconds` | Number of seconds before probe is initiated. | `30` | +| `readinessProbe.periodSeconds` | How often (in seconds) to perform the probe. | `10` | +| `readinessProbe.timeoutSeconds` | Number of seconds after which the probe times out. | `5` | +| `readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed. | `1` | +| `readinessProbe.failureThreshold` | After the probe fails this many times, pod will be marked Unready. | `3` | +| `terminationGracePeriodSeconds` | Wait up to this many seconds for a broker to shut down gracefully, after which it is killed | `60` | +| `updateStrategy` | StatefulSet update strategy to use. | `{ type: "OnDelete" }` | +| `podManagementPolicy` | Start and stop pods in Parallel or OrderedReady (one-by-one.) Can not change after first release. | `OrderedReady` | +| `persistence.enabled` | Use a PVC to persist data | `true` | +| `persistence.size` | Size of data volume | `1Gi` | +| `persistence.mountPath` | Mount path of data volume | `/opt/kafka/data` | +| `persistence.storageClass` | Storage class of backing PVC | `nil` | +| `jmx.configMap.enabled` | Enable the default ConfigMap for JMX | `true` | +| `jmx.configMap.overrideConfig` | Allows config file to be generated by passing values to ConfigMap | `{}` | +| `jmx.configMap.overrideName` | Allows setting the name of the ConfigMap to be used | `""` | +| `jmx.port` | The jmx port which JMX style metrics are exposed (note: these are not scrapeable by Prometheus) | `5555` | +| `jmx.whitelistObjectNames` | Allows setting which JMX objects you want to expose to via JMX stats to JMX Exporter | (see `values.yaml`) | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `prometheus.jmx.resources` | Allows setting resource limits for jmx sidecar container | `{}` | +| `prometheus.jmx.enabled` | Whether or not to expose JMX metrics to Prometheus | `false` | +| `prometheus.jmx.image` | JMX Exporter container image | `solsson/kafka-prometheus-jmx-exporter@sha256` | +| `prometheus.jmx.imageTag` | JMX Exporter container image tag | `a23062396cd5af1acdf76512632c20ea6be76885dfc20cd9ff40fb23846557e8` | +| `prometheus.jmx.interval` | Interval that Prometheus scrapes JMX metrics when using Prometheus Operator | `10s` | +| `prometheus.jmx.scrapeTimeout` | Timeout that Prometheus scrapes JMX metrics when using Prometheus Operator | `10s` | +| `prometheus.jmx.port` | JMX Exporter Port which exposes metrics in Prometheus format for scraping | `5556` | +| `prometheus.kafka.enabled` | Whether or not to create a separate Kafka exporter | `false` | +| `prometheus.kafka.image` | Kafka Exporter container image | `danielqsj/kafka-exporter` | +| `prometheus.kafka.imageTag` | Kafka Exporter container image tag | `v1.2.0` | +| `prometheus.kafka.interval` | Interval that Prometheus scrapes Kafka metrics when using Prometheus Operator | `10s` | +| `prometheus.kafka.scrapeTimeout` | Timeout that Prometheus scrapes Kafka metrics when using Prometheus Operator | `10s` | +| `prometheus.kafka.port` | Kafka Exporter Port which exposes metrics in Prometheus format for scraping | `9308` | +| `prometheus.kafka.resources` | Allows setting resource limits for kafka-exporter pod | `{}` | +| `prometheus.kafka.affinity` | Defines affinities and anti-affinities for pods as defined in: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity preferences | `{}` | +| `prometheus.kafka.tolerations` | List of node tolerations for the pods. https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | `[]` | +| `prometheus.operator.enabled` | True if using the Prometheus Operator, False if not | `false` | +| `prometheus.operator.serviceMonitor.namespace` | Namespace in which to install the ServiceMonitor resource. Default to kube-prometheus install. | `monitoring` | +| `prometheus.operator.serviceMonitor.releaseNamespace` | Set namespace to release namespace. Default false | `false` | +| `prometheus.operator.serviceMonitor.selector` | Default to kube-prometheus install (CoreOS recommended), but should be set according to Prometheus install | `{ prometheus: kube-prometheus }` | +| `prometheus.operator.prometheusRule.enabled` | True to create a PrometheusRule resource for Prometheus Operator, False if not | `false` | +| `prometheus.operator.prometheusRule.namespace` | Namespace in which to install the PrometheusRule resource. Default to kube-prometheus install. | `monitoring` | +| `prometheus.operator.prometheusRule.releaseNamespace` | Set namespace to release namespace. Default false | `false` | +| `prometheus.operator.prometheusRule.selector` | Default to kube-prometheus install (CoreOS recommended), but should be set according to Prometheus install | `{ prometheus: kube-prometheus }` | +| `prometheus.operator.prometheusRule.rules` | Define the prometheus rules. See values file for examples | `{}` | +| `configJob.backoffLimit` | Number of retries before considering kafka-config job as failed | `6` | +| `topics` | List of topics to create & configure. Can specify name, partitions, replicationFactor, reassignPartitions, config. See values.yaml | `[]` (Empty list) | +| `zookeeper.enabled` | If True, installs Zookeeper Chart | `true` | +| `zookeeper.resources` | Zookeeper resource requests and limits | `{}` | +| `zookeeper.env` | Environmental variables provided to Zookeeper Zookeeper | `{ZK_HEAP_SIZE: "1G"}` | +| `zookeeper.storage` | Zookeeper Persistent volume size | `2Gi` | +| `zookeeper.image.PullPolicy` | Zookeeper Container pull policy | `IfNotPresent` | +| `zookeeper.url` | URL of Zookeeper Cluster (unneeded if installing Zookeeper Chart) | `""` | +| `zookeeper.port` | Port of Zookeeper Cluster | `2181` | +| `zookeeper.affinity` | Defines affinities and anti-affinities for pods as defined in: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity preferences | `{}` | +| `zookeeper.nodeSelector` | Node labels for pod assignment | `{}` | + +Specify parameters using `--set key=value[,key=value]` argument to `helm install` + +Alternatively a YAML file that specifies the values for the parameters can be provided like this: + +```bash +$ helm install --name my-kafka -f values.yaml incubator/kafka +``` + +### Connecting to Kafka from inside Kubernetes + +You can connect to Kafka by running a simple pod in the K8s cluster like this with a configuration like this: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: testclient + namespace: kafka +spec: + containers: + - name: kafka + image: solsson/kafka:0.11.0.0 + command: + - sh + - -c + - "exec tail -f /dev/null" +``` + +Once you have the testclient pod above running, you can list all kafka +topics with: + +` kubectl -n kafka exec -ti testclient -- ./bin/kafka-topics.sh --zookeeper +my-release-zookeeper:2181 --list` + +Where `my-release` is the name of your helm release. + +## Extensions + +Kafka has a rich ecosystem, with lots of tools. This sections is intended to compile all of those tools for which a corresponding Helm chart has already been created. + +- [Schema-registry](https://github.com/kubernetes/charts/tree/master/incubator/schema-registry) - A confluent project that provides a serving layer for your metadata. It provides a RESTful interface for storing and retrieving Avro schemas. + +## Connecting to Kafka from outside Kubernetes + +### NodePort External Service Type + +Review and optionally override to enable the example text concerned with external access in `values.yaml`. + +Once configured, you should be able to reach Kafka via NodePorts, one per replica. In kops where private, +topology is enabled, this feature publishes an internal round-robin DNS record using the following naming +scheme. The external access feature of this chart was tested with kops on AWS using flannel networking. +If you wish to enable external access to Kafka running in kops, your security groups will likely need to +be adjusted to allow non-Kubernetes nodes (e.g. bastion) to access the Kafka external listener port range. + +``` +{{ .Release.Name }}.{{ .Values.external.domain }} +``` + +If `external.distinct` is set theses entries will be prefixed with the replica number or broker id. + +``` +{{ .Release.Name }}-.{{ .Values.external.domain }} +``` + +Port numbers for external access used at container and NodePort are unique to each container in the StatefulSet. +Using the default `external.firstListenerPort` number with a `replicas` value of `3`, the following +container and NodePorts will be opened for external access: `31090`, `31091`, `31092`. All of these ports should +be reachable from any host to NodePorts are exposed because Kubernetes routes each NodePort from entry node +to pod/container listening on the same port (e.g. `31091`). + +The `external.servicePort` at each external access service (one such service per pod) is a relay toward +the a `containerPort` with a number matching its respective `NodePort`. The range of NodePorts is set, but +should not actually listen, on all Kafka pods in the StatefulSet. As any given pod will listen only one +such port at a time, setting the range at every Kafka pod is a reasonably safe configuration. + +#### Example values.yml for external service type NodePort +The + lines are with the updated values. +``` + external: +- enabled: false ++ enabled: true + # type can be either NodePort or LoadBalancer + type: NodePort + # annotations: +@@ -170,14 +170,14 @@ configurationOverrides: + ## + ## Setting "advertised.listeners" here appends to "PLAINTEXT://${POD_IP}:9092,", ensure you update the domain + ## If external service type is Nodeport: +- # "advertised.listeners": |- +- # EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) ++ "advertised.listeners": |- ++ EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) + ## If external service type is LoadBalancer and distinct is true: + # "advertised.listeners": |- + # EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).cluster.local:19092 + ## If external service type is LoadBalancer and distinct is false: + # "advertised.listeners": |- + # EXTERNAL://EXTERNAL://${LOAD_BALANCER_IP}:31090 + ## Uncomment to define the EXTERNAL Listener protocol +- # "listener.security.protocol.map": |- +- # PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT ++ "listener.security.protocol.map": |- ++ PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT + + +$ kafkacat -b kafka.cluster.local:31090 -L +Metadata for all topics (from broker 0: kafka.cluster.local:31090/0): + 3 brokers: + broker 2 at kafka.cluster.local:31092 + broker 1 at kafka.cluster.local:31091 + broker 0 at kafka.cluster.local:31090 + 0 topics: + +$ kafkacat -b kafka.cluster.local:31090 -P -t test1 -p 0 +msg01 from external producer to topic test1 + +$ kafkacat -b kafka.cluster.local:31090 -C -t test1 -p 0 +msg01 from external producer to topic test1 +``` +### LoadBalancer External Service Type + +The load balancer external service type differs from the node port type by routing to the `external.servicePort` specified in the service for each statefulset container (if `external.distinct` is set). If `external.distinct` is false, `external.servicePort` is unused and will be set to the sum of `external.firstListenerPort` and the replica number. It is important to note that `external.firstListenerPort` does not have to be within the configured node port range for the cluster, however a node port will be allocated. + +#### Example values.yml and DNS setup for external service type LoadBalancer with external.distinct: true +The + lines are with the updated values. +``` + external: +- enabled: false ++ enabled: true + # type can be either NodePort or LoadBalancer +- type: NodePort ++ type: LoadBalancer + # annotations: + # service.beta.kubernetes.io/openstack-internal-load-balancer: "true" + dns: +@@ -138,10 +138,10 @@ external: + # If using external service type LoadBalancer and external dns, set distinct to true below. + # This creates an A record for each statefulset pod/broker. You should then map the + # A record of the broker to the EXTERNAL IP given by the LoadBalancer in your DNS server. +- distinct: false ++ distinct: true + servicePort: 19092 + firstListenerPort: 31090 +- domain: cluster.local ++ domain: example.com + loadBalancerIP: [] + init: + image: "lwolf/kubectl_deployer" +@@ -173,11 +173,11 @@ configurationOverrides: + # "advertised.listeners": |- + # EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) + ## If external service type is LoadBalancer and distinct is true: +- # "advertised.listeners": |- +- # EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).cluster.local:19092 ++ "advertised.listeners": |- ++ EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).example.com:19092 + ## Uncomment to define the EXTERNAL Listener protocol +- # "listener.security.protocol.map": |- +- # PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT ++ "listener.security.protocol.map": |- ++ PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT + +$ kubectl -n kafka get svc +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +kafka ClusterIP 10.39.241.217 9092/TCP 2m39s +kafka-0-external LoadBalancer 10.39.242.45 35.200.238.174 19092:30108/TCP 2m39s +kafka-1-external LoadBalancer 10.39.241.90 35.244.44.162 19092:30582/TCP 2m39s +kafka-2-external LoadBalancer 10.39.243.160 35.200.149.80 19092:30539/TCP 2m39s +kafka-headless ClusterIP None 9092/TCP 2m39s +kafka-zookeeper ClusterIP 10.39.249.70 2181/TCP 2m39s +kafka-zookeeper-headless ClusterIP None 2181/TCP,3888/TCP,2888/TCP 2m39s + +DNS A record entries: +kafka-0.example.com A record 35.200.238.174 TTL 60sec +kafka-1.example.com A record 35.244.44.162 TTL 60sec +kafka-2.example.com A record 35.200.149.80 TTL 60sec + +$ ping kafka-0.example.com +PING kafka-0.example.com (35.200.238.174): 56 data bytes + +$ kafkacat -b kafka-0.example.com:19092 -L +Metadata for all topics (from broker 0: kafka-0.example.com:19092/0): + 3 brokers: + broker 2 at kafka-2.example.com:19092 + broker 1 at kafka-1.example.com:19092 + broker 0 at kafka-0.example.com:19092 + 0 topics: + +$ kafkacat -b kafka-0.example.com:19092 -P -t gkeTest -p 0 +msg02 for topic gkeTest + +$ kafkacat -b kafka-0.example.com:19092 -C -t gkeTest -p 0 +msg02 for topic gkeTest +``` + +#### Example values.yml and DNS setup for external service type LoadBalancer with external.distinct: false +The + lines are with the updated values. +``` + external: +- enabled: false ++ enabled: true + # type can be either NodePort or LoadBalancer +- type: NodePort ++ type: LoadBalancer + # annotations: + # service.beta.kubernetes.io/openstack-internal-load-balancer: "true" + dns: +@@ -138,10 +138,10 @@ external: + distinct: false + servicePort: 19092 + firstListenerPort: 31090 + domain: cluster.local + loadBalancerIP: [35.200.238.174,35.244.44.162,35.200.149.80] + init: + image: "lwolf/kubectl_deployer" +@@ -173,11 +173,11 @@ configurationOverrides: + # "advertised.listeners": |- + # EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) + ## If external service type is LoadBalancer and distinct is true: +- # "advertised.listeners": |- +- # EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).cluster.local:19092 ++ "advertised.listeners": |- ++ EXTERNAL://${LOAD_BALANCER_IP}:31090 + ## Uncomment to define the EXTERNAL Listener protocol +- # "listener.security.protocol.map": |- +- # PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT ++ "listener.security.protocol.map": |- ++ PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT + +$ kubectl -n kafka get svc +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +kafka ClusterIP 10.39.241.217 9092/TCP 2m39s +kafka-0-external LoadBalancer 10.39.242.45 35.200.238.174 31090:30108/TCP 2m39s +kafka-1-external LoadBalancer 10.39.241.90 35.244.44.162 31090:30582/TCP 2m39s +kafka-2-external LoadBalancer 10.39.243.160 35.200.149.80 31090:30539/TCP 2m39s +kafka-headless ClusterIP None 9092/TCP 2m39s +kafka-zookeeper ClusterIP 10.39.249.70 2181/TCP 2m39s +kafka-zookeeper-headless ClusterIP None 2181/TCP,3888/TCP,2888/TCP 2m39s + +$ kafkacat -b 35.200.238.174:31090 -L +Metadata for all topics (from broker 0: 35.200.238.174:31090/0): + 3 brokers: + broker 2 at 35.200.149.80:31090 + broker 1 at 35.244.44.162:31090 + broker 0 at 35.200.238.174:31090 + 0 topics: + +$ kafkacat -b 35.200.238.174:31090 -P -t gkeTest -p 0 +msg02 for topic gkeTest + +$ kafkacat -b 35.200.238.174:31090 -C -t gkeTest -p 0 +msg02 for topic gkeTest +``` + +## Known Limitations + +* Only supports storage options that have backends for persistent volume claims (tested mostly on AWS) +* KAFKA_PORT will be created as an envvar and brokers will fail to start when there is a service named `kafka` in the same namespace. We work around this be unsetting that envvar `unset KAFKA_PORT`. + +[brokerconfigs]: https://kafka.apache.org/documentation/#brokerconfigs + +## Prometheus Stats + +### Prometheus vs Prometheus Operator + +Standard Prometheus is the default monitoring option for this chart. This chart also supports the CoreOS Prometheus Operator, +which can provide additional functionality like automatically updating Prometheus and Alert Manager configuration. If you are +interested in installing the Prometheus Operator please see the [CoreOS repository](https://github.com/coreos/prometheus-operator/tree/master/helm) for more information or +read through the [CoreOS blog post introducing the Prometheus Operator](https://coreos.com/blog/the-prometheus-operator.html) + +### JMX Exporter + +The majority of Kafka statistics are provided via JMX and are exposed via the [Prometheus JMX Exporter](https://github.com/prometheus/jmx_exporter). + +The JMX Exporter is a general purpose prometheus provider which is intended for use with any Java application. Because of this, it produces a number of statistics which +may not be of interest. To help in reducing these statistics to their relevant components we have created a curated whitelist `whitelistObjectNames` for the JMX exporter. +This whitelist may be modified or removed via the values configuration. + +To accommodate compatibility with the Prometheus metrics, this chart performs transformations of raw JMX metrics. For example, broker names and topics names are incorporated +into the metric name instead of becoming a label. If you are curious to learn more about any default transformations to the chart metrics, please have reference the [configmap template](https://github.com/kubernetes/charts/blob/master/incubator/kafka/templates/jmx-configmap.yaml). + +### Kafka Exporter + +The [Kafka Exporter](https://github.com/danielqsj/kafka_exporter) is a complementary metrics exporter to the JMX Exporter. The Kafka Exporter provides additional statistics on Kafka Consumer Groups. diff --git a/infra/charts/feast/charts/postgresql/README.md b/infra/charts/feast/charts/postgresql/README.md index 2469239df24..1db8289f993 100644 --- a/infra/charts/feast/charts/postgresql/README.md +++ b/infra/charts/feast/charts/postgresql/README.md @@ -1,134 +1,566 @@ -postgresql -========== -Chart for PostgreSQL, an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance. - -Current chart version is `8.6.1` - -Source code can be found [here](https://www.postgresql.org/) - - - -## Chart Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| extraEnv | list | `[]` | | -| global.postgresql | object | `{}` | | -| image.debug | bool | `false` | | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.registry | string | `"docker.io"` | | -| image.repository | string | `"bitnami/postgresql"` | | -| image.tag | string | `"11.7.0-debian-10-r9"` | | -| ldap.baseDN | string | `""` | | -| ldap.bindDN | string | `""` | | -| ldap.bind_password | string | `nil` | | -| ldap.enabled | bool | `false` | | -| ldap.port | string | `""` | | -| ldap.prefix | string | `""` | | -| ldap.scheme | string | `""` | | -| ldap.search_attr | string | `""` | | -| ldap.search_filter | string | `""` | | -| ldap.server | string | `""` | | -| ldap.suffix | string | `""` | | -| ldap.tls | bool | `false` | | -| ldap.url | string | `""` | | -| livenessProbe.enabled | bool | `true` | | -| livenessProbe.failureThreshold | int | `6` | | -| livenessProbe.initialDelaySeconds | int | `30` | | -| livenessProbe.periodSeconds | int | `10` | | -| livenessProbe.successThreshold | int | `1` | | -| livenessProbe.timeoutSeconds | int | `5` | | -| master.affinity | object | `{}` | | -| master.annotations | object | `{}` | | -| master.extraInitContainers | string | `"# - name: do-something\n# image: busybox\n# command: ['do', 'something']\n"` | | -| master.extraVolumeMounts | list | `[]` | | -| master.extraVolumes | list | `[]` | | -| master.labels | object | `{}` | | -| master.nodeSelector | object | `{}` | | -| master.podAnnotations | object | `{}` | | -| master.podLabels | object | `{}` | | -| master.priorityClassName | string | `""` | | -| master.sidecars | list | `[]` | | -| master.tolerations | list | `[]` | | -| metrics.enabled | bool | `false` | | -| metrics.image.pullPolicy | string | `"IfNotPresent"` | | -| metrics.image.registry | string | `"docker.io"` | | -| metrics.image.repository | string | `"bitnami/postgres-exporter"` | | -| metrics.image.tag | string | `"0.8.0-debian-10-r28"` | | -| metrics.livenessProbe.enabled | bool | `true` | | -| metrics.livenessProbe.failureThreshold | int | `6` | | -| metrics.livenessProbe.initialDelaySeconds | int | `5` | | -| metrics.livenessProbe.periodSeconds | int | `10` | | -| metrics.livenessProbe.successThreshold | int | `1` | | -| metrics.livenessProbe.timeoutSeconds | int | `5` | | -| metrics.prometheusRule.additionalLabels | object | `{}` | | -| metrics.prometheusRule.enabled | bool | `false` | | -| metrics.prometheusRule.namespace | string | `""` | | -| metrics.prometheusRule.rules | list | `[]` | | -| metrics.readinessProbe.enabled | bool | `true` | | -| metrics.readinessProbe.failureThreshold | int | `6` | | -| metrics.readinessProbe.initialDelaySeconds | int | `5` | | -| metrics.readinessProbe.periodSeconds | int | `10` | | -| metrics.readinessProbe.successThreshold | int | `1` | | -| metrics.readinessProbe.timeoutSeconds | int | `5` | | -| metrics.securityContext.enabled | bool | `false` | | -| metrics.securityContext.runAsUser | int | `1001` | | -| metrics.service.annotations."prometheus.io/port" | string | `"9187"` | | -| metrics.service.annotations."prometheus.io/scrape" | string | `"true"` | | -| metrics.service.loadBalancerIP | string | `nil` | | -| metrics.service.type | string | `"ClusterIP"` | | -| metrics.serviceMonitor.additionalLabels | object | `{}` | | -| metrics.serviceMonitor.enabled | bool | `false` | | -| networkPolicy.allowExternal | bool | `true` | | -| networkPolicy.enabled | bool | `false` | | -| persistence.accessModes[0] | string | `"ReadWriteOnce"` | | -| persistence.annotations | object | `{}` | | -| persistence.enabled | bool | `true` | | -| persistence.mountPath | string | `"/bitnami/postgresql"` | | -| persistence.size | string | `"8Gi"` | | -| persistence.subPath | string | `""` | | -| postgresqlDataDir | string | `"/bitnami/postgresql/data"` | | -| postgresqlUsername | string | `"postgres"` | | -| readinessProbe.enabled | bool | `true` | | -| readinessProbe.failureThreshold | int | `6` | | -| readinessProbe.initialDelaySeconds | int | `5` | | -| readinessProbe.periodSeconds | int | `10` | | -| readinessProbe.successThreshold | int | `1` | | -| readinessProbe.timeoutSeconds | int | `5` | | -| replication.applicationName | string | `"my_application"` | | -| replication.enabled | bool | `false` | | -| replication.numSynchronousReplicas | int | `0` | | -| replication.password | string | `"repl_password"` | | -| replication.slaveReplicas | int | `1` | | -| replication.synchronousCommit | string | `"off"` | | -| replication.user | string | `"repl_user"` | | -| resources.requests.cpu | string | `"250m"` | | -| resources.requests.memory | string | `"256Mi"` | | -| securityContext.enabled | bool | `true` | | -| securityContext.fsGroup | int | `1001` | | -| securityContext.runAsUser | int | `1001` | | -| service.annotations | object | `{}` | | -| service.port | int | `5432` | | -| service.type | string | `"ClusterIP"` | | -| serviceAccount.enabled | bool | `false` | | -| shmVolume.chmod.enabled | bool | `true` | | -| shmVolume.enabled | bool | `true` | | -| slave.affinity | object | `{}` | | -| slave.annotations | object | `{}` | | -| slave.extraInitContainers | string | `"# - name: do-something\n# image: busybox\n# command: ['do', 'something']\n"` | | -| slave.extraVolumeMounts | list | `[]` | | -| slave.extraVolumes | list | `[]` | | -| slave.labels | object | `{}` | | -| slave.nodeSelector | object | `{}` | | -| slave.podAnnotations | object | `{}` | | -| slave.podLabels | object | `{}` | | -| slave.priorityClassName | string | `""` | | -| slave.sidecars | list | `[]` | | -| slave.tolerations | list | `[]` | | -| updateStrategy.type | string | `"RollingUpdate"` | | -| volumePermissions.enabled | bool | `false` | | -| volumePermissions.image.pullPolicy | string | `"Always"` | | -| volumePermissions.image.registry | string | `"docker.io"` | | -| volumePermissions.image.repository | string | `"bitnami/minideb"` | | -| volumePermissions.image.tag | string | `"buster"` | | -| volumePermissions.securityContext.runAsUser | int | `0` | | +# PostgreSQL + +[PostgreSQL](https://www.postgresql.org/) is an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance. + +For HA, please see [this repo](https://github.com/bitnami/charts/tree/master/bitnami/postgresql-ha) + +## TL;DR; + +```console +$ helm install my-release stable/postgresql +``` + +## Introduction + +This chart bootstraps a [PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.com/) for deployment and management of Helm Charts in clusters. This chart has been tested to work with NGINX Ingress, cert-manager, fluentd and Prometheus on top of the [BKPR](https://kubeprod.io/). + +## Prerequisites + +- Kubernetes 1.12+ +- Helm 2.11+ or Helm 3.0-beta3+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart +To install the chart with the release name `my-release`: + +```console +$ helm install my-release stable/postgresql +``` + +The command deploys PostgreSQL on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## 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. + +## Parameters + +The following tables lists the configurable parameters of the PostgreSQL chart and their default values. + +| Parameter | Description | Default | +|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------| +| `global.imageRegistry` | Global Docker Image registry | `nil` | +| `global.postgresql.postgresqlDatabase` | PostgreSQL database (overrides `postgresqlDatabase`) | `nil` | +| `global.postgresql.postgresqlUsername` | PostgreSQL username (overrides `postgresqlUsername`) | `nil` | +| `global.postgresql.existingSecret` | Name of existing secret to use for PostgreSQL passwords (overrides `existingSecret`) | `nil` | +| `global.postgresql.postgresqlPassword` | PostgreSQL admin password (overrides `postgresqlPassword`) | `nil` | +| `global.postgresql.servicePort` | PostgreSQL port (overrides `service.port`) | `nil` | +| `global.postgresql.replicationPassword` | Replication user password (overrides `replication.password`) | `nil` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) | +| `global.storageClass` | Global storage class for dynamic provisioning | `nil` | +| `image.registry` | PostgreSQL Image registry | `docker.io` | +| `image.repository` | PostgreSQL Image name | `bitnami/postgresql` | +| `image.tag` | PostgreSQL Image tag | `{TAG_NAME}` | +| `image.pullPolicy` | PostgreSQL Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Specify Image pull secrets | `nil` (does not add image pull secrets to deployed pods) | +| `image.debug` | Specify if debug values should be set | `false` | +| `nameOverride` | String to partially override postgresql.fullname template with a string (will prepend the release name) | `nil` | +| `fullnameOverride` | String to fully override postgresql.fullname template with a string | `nil` | +| `volumePermissions.enabled` | Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | +| `volumePermissions.image.repository` | Init container volume-permissions image name | `bitnami/minideb` | +| `volumePermissions.image.tag` | Init container volume-permissions image tag | `buster` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `Always` | +| `volumePermissions.securityContext.runAsUser` | User ID for the init container (when facing issues in OpenShift or uid unknown, try value "auto") | `0` | +| `usePasswordFile` | Have the secrets mounted as a file instead of env vars | `false` | +| `ldap.enabled` | Enable LDAP support | `false` | +| `ldap.existingSecret` | Name of existing secret to use for LDAP passwords | `nil` | +| `ldap.url` | LDAP URL beginning in the form `ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]]` | `nil` | +| `ldap.server` | IP address or name of the LDAP server. | `nil` | +| `ldap.port` | Port number on the LDAP server to connect to | `nil` | +| `ldap.scheme` | Set to `ldaps` to use LDAPS. | `nil` | +| `ldap.tls` | Set to `1` to use TLS encryption | `nil` | +| `ldap.prefix` | String to prepend to the user name when forming the DN to bind | `nil` | +| `ldap.suffix` | String to append to the user name when forming the DN to bind | `nil` | +| `ldap.search_attr` | Attribute to match agains the user name in the search | `nil` | +| `ldap.search_filter` | The search filter to use when doing search+bind authentication | `nil` | +| `ldap.baseDN` | Root DN to begin the search for the user in | `nil` | +| `ldap.bindDN` | DN of user to bind to LDAP | `nil` | +| `ldap.bind_password` | Password for the user to bind to LDAP | `nil` | +| `replication.enabled` | Enable replication | `false` | +| `replication.user` | Replication user | `repl_user` | +| `replication.password` | Replication user password | `repl_password` | +| `replication.slaveReplicas` | Number of slaves replicas | `1` | +| `replication.synchronousCommit` | Set synchronous commit mode. Allowed values: `on`, `remote_apply`, `remote_write`, `local` and `off` | `off` | +| `replication.numSynchronousReplicas` | Number of replicas that will have synchronous replication. Note: Cannot be greater than `replication.slaveReplicas`. | `0` | +| `replication.applicationName` | Cluster application name. Useful for advanced replication settings | `my_application` | +| `existingSecret` | Name of existing secret to use for PostgreSQL passwords. The secret has to contain the keys `postgresql-postgres-password` which is the password for `postgresqlUsername` when it is different of `postgres`, `postgresql-password` which will override `postgresqlPassword`, `postgresql-replication-password` which will override `replication.password` and `postgresql-ldap-password` which will be sed to authenticate on LDAP. | `nil` | +| `postgresqlPostgresPassword` | PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`) | _random 10 character alphanumeric string_ | +| `postgresqlUsername` | PostgreSQL admin user | `postgres` | +| `postgresqlPassword` | PostgreSQL admin password | _random 10 character alphanumeric string_ | +| `postgresqlDatabase` | PostgreSQL database | `nil` | +| `postgresqlDataDir` | PostgreSQL data dir folder | `/bitnami/postgresql` (same value as persistence.mountPath) | +| `extraEnv` | Any extra environment variables you would like to pass on to the pod. The value is evaluated as a template. | `[]` | +| `extraEnvVarsCM` | Name of a Config Map containing extra environment variables you would like to pass on to the pod. | `nil` | +| `postgresqlInitdbArgs` | PostgreSQL initdb extra arguments | `nil` | +| `postgresqlInitdbWalDir` | PostgreSQL location for transaction log | `nil` | +| `postgresqlConfiguration` | Runtime Config Parameters | `nil` | +| `postgresqlExtendedConf` | Extended Runtime Config Parameters (appended to main or default configuration) | `nil` | +| `pgHbaConfiguration` | Content of pg_hba.conf | `nil (do not create pg_hba.conf)` | +| `configurationConfigMap` | ConfigMap with the PostgreSQL configuration files (Note: Overrides `postgresqlConfiguration` and `pgHbaConfiguration`). The value is evaluated as a template. | `nil` | +| `extendedConfConfigMap` | ConfigMap with the extended PostgreSQL configuration files. The value is evaluated as a template. | `nil` | +| `initdbScripts` | Dictionary of initdb scripts | `nil` | +| `initdbUsername` | PostgreSQL user to execute the .sql and sql.gz scripts | `nil` | +| `initdbPassword` | Password for the user specified in `initdbUsername` | `nil` | +| `initdbScriptsConfigMap` | ConfigMap with the initdb scripts (Note: Overrides `initdbScripts`). The value is evaluated as a template. | `nil` | +| `initdbScriptsSecret` | Secret with initdb scripts that contain sensitive information (Note: can be used with `initdbScriptsConfigMap` or `initdbScripts`). The value is evaluated as a template. | `nil` | +| `service.type` | Kubernetes Service type | `ClusterIP` | +| `service.port` | PostgreSQL port | `5432` | +| `service.nodePort` | Kubernetes Service nodePort | `nil` | +| `service.annotations` | Annotations for PostgreSQL service, the value is evaluated as a template. | {} | +| `service.loadBalancerIP` | loadBalancerIP if service type is `LoadBalancer` | `nil` | +| `service.loadBalancerSourceRanges` | Address that are allowed when svc is LoadBalancer | [] | +| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | +| `shmVolume.enabled` | Enable emptyDir volume for /dev/shm for master and slave(s) Pod(s) | `true` | +| `shmVolume.chmod.enabled` | Run at init chmod 777 of the /dev/shm (ignored if `volumePermissions.enabled` is `false`) | `true` | +| `persistence.enabled` | Enable persistence using PVC | `true` | +| `persistence.existingClaim` | Provide an existing `PersistentVolumeClaim`, the value is evaluated as a template. | `nil` | +| `persistence.mountPath` | Path to mount the volume at | `/bitnami/postgresql` | +| `persistence.subPath` | Subdirectory of the volume to mount at | `""` | +| `persistence.storageClass` | PVC Storage Class for PostgreSQL volume | `nil` | +| `persistence.accessModes` | PVC Access Mode for PostgreSQL volume | `[ReadWriteOnce]` | +| `persistence.size` | PVC Storage Request for PostgreSQL volume | `8Gi` | +| `persistence.annotations` | Annotations for the PVC | `{}` | +| `master.nodeSelector` | Node labels for pod assignment (postgresql master) | `{}` | +| `master.affinity` | Affinity labels for pod assignment (postgresql master) | `{}` | +| `master.tolerations` | Toleration labels for pod assignment (postgresql master) | `[]` | +| `master.anotations` | Map of annotations to add to the statefulset (postgresql master) | `{}` | +| `master.labels` | Map of labels to add to the statefulset (postgresql master) | `{}` | +| `master.podAnnotations` | Map of annotations to add to the pods (postgresql master) | `{}` | +| `master.podLabels` | Map of labels to add to the pods (postgresql master) | `{}` | +| `master.priorityClassName` | Priority Class to use for each pod (postgresql master) | `nil` | +| `master.extraInitContainers` | Additional init containers to add to the pods (postgresql master) | `[]` | +| `master.extraVolumeMounts` | Additional volume mounts to add to the pods (postgresql master) | `[]` | +| `master.extraVolumes` | Additional volumes to add to the pods (postgresql master) | `[]` | +| `master.sidecars` | Add additional containers to the pod | `[]` | +| `slave.nodeSelector` | Node labels for pod assignment (postgresql slave) | `{}` | +| `slave.affinity` | Affinity labels for pod assignment (postgresql slave) | `{}` | +| `slave.tolerations` | Toleration labels for pod assignment (postgresql slave) | `[]` | +| `slave.anotations` | Map of annotations to add to the statefulsets (postgresql slave) | `{}` | +| `slave.labels` | Map of labels to add to the statefulsets (postgresql slave) | `{}` | +| `slave.podAnnotations` | Map of annotations to add to the pods (postgresql slave) | `{}` | +| `slave.podLabels` | Map of labels to add to the pods (postgresql slave) | `{}` | +| `slave.priorityClassName` | Priority Class to use for each pod (postgresql slave) | `nil` | +| `slave.extraInitContainers` | Additional init containers to add to the pods (postgresql slave) | `[]` | +| `slave.extraVolumeMounts` | Additional volume mounts to add to the pods (postgresql slave) | `[]` | +| `slave.extraVolumes` | Additional volumes to add to the pods (postgresql slave) | `[]` | +| `slave.sidecars` | Add additional containers to the pod | `[]` | +| `terminationGracePeriodSeconds` | Seconds the pod needs to terminate gracefully | `nil` | +| `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `250m` | +| `securityContext.enabled` | Enable security context | `true` | +| `securityContext.fsGroup` | Group ID for the container | `1001` | +| `securityContext.runAsUser` | User ID for the container | `1001` | +| `serviceAccount.enabled` | Enable service account (Note: Service Account will only be automatically created if `serviceAccount.name` is not set) | `false` | +| `serviceAcccount.name` | Name of existing service account | `nil` | +| `livenessProbe.enabled` | Would you like a livenessProbe to be enabled | `true` | +| `networkPolicy.enabled` | Enable NetworkPolicy | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which ingress traffic could be allowed | `nil` | +| `livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 30 | +| `livenessProbe.periodSeconds` | How often to perform the probe | 10 | +| `livenessProbe.timeoutSeconds` | When the probe times out | 5 | +| `livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 | +| `livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 | +| `readinessProbe.enabled` | would you like a readinessProbe to be enabled | `true` | +| `readinessProbe.initialDelaySeconds` | Delay before readiness probe is initiated | 5 | +| `readinessProbe.periodSeconds` | How often to perform the probe | 10 | +| `readinessProbe.timeoutSeconds` | When the probe times out | 5 | +| `readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 | +| `readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 | +| `metrics.enabled` | Start a prometheus exporter | `false` | +| `metrics.service.type` | Kubernetes Service type | `ClusterIP` | +| `service.clusterIP` | Static clusterIP or None for headless services | `nil` | +| `metrics.service.annotations` | Additional annotations for metrics exporter pod | `{ prometheus.io/scrape: "true", prometheus.io/port: "9187"}` | +| `metrics.service.loadBalancerIP` | loadBalancerIP if redis metrics service type is `LoadBalancer` | `nil` | +| `metrics.serviceMonitor.enabled` | Set this to `true` to create ServiceMonitor for Prometheus operator | `false` | +| `metrics.serviceMonitor.additionalLabels` | Additional labels that can be used so ServiceMonitor will be discovered by Prometheus | `{}` | +| `metrics.serviceMonitor.namespace` | Optional namespace in which to create ServiceMonitor | `nil` | +| `metrics.serviceMonitor.interval` | Scrape interval. If not set, the Prometheus default scrape interval is used | `nil` | +| `metrics.serviceMonitor.scrapeTimeout` | Scrape timeout. If not set, the Prometheus default scrape timeout is used | `nil` | +| `metrics.prometheusRule.enabled` | Set this to true to create prometheusRules for Prometheus operator | `false` | +| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so prometheusRules will be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.namespace` | namespace where prometheusRules resource should be created | the same namespace as postgresql | +| `metrics.prometheusRule.rules` | [rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) to be created, check values for an example. | `[]` | +| `metrics.image.registry` | PostgreSQL Image registry | `docker.io` | +| `metrics.image.repository` | PostgreSQL Image name | `bitnami/postgres-exporter` | +| `metrics.image.tag` | PostgreSQL Image tag | `{TAG_NAME}` | +| `metrics.image.pullPolicy` | PostgreSQL Image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify Image pull secrets | `nil` (does not add image pull secrets to deployed pods) | +| `metrics.customMetrics` | Additional custom metrics | `nil` | +| `metrics.securityContext.enabled` | Enable security context for metrics | `false` | +| `metrics.securityContext.runAsUser` | User ID for the container for metrics | `1001` | +| `metrics.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 30 | +| `metrics.livenessProbe.periodSeconds` | How often to perform the probe | 10 | +| `metrics.livenessProbe.timeoutSeconds` | When the probe times out | 5 | +| `metrics.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 | +| `metrics.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 | +| `metrics.readinessProbe.enabled` | would you like a readinessProbe to be enabled | `true` | +| `metrics.readinessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 5 | +| `metrics.readinessProbe.periodSeconds` | How often to perform the probe | 10 | +| `metrics.readinessProbe.timeoutSeconds` | When the probe times out | 5 | +| `metrics.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 | +| `metrics.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 | +| `updateStrategy` | Update strategy policy | `{type: "RollingUpdate"}` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install my-release \ + --set postgresqlPassword=secretpassword,postgresqlDatabase=my-database \ + stable/postgresql +``` + +The above command sets the PostgreSQL `postgres` account password to `secretpassword`. Additionally it creates a database named `my-database`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```console +$ helm install my-release -f values.yaml stable/postgresql +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## Configuration and installation details + +### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Production configuration and horizontal scaling + +This chart includes a `values-production.yaml` file where you can find some parameters oriented to production configuration in comparison to the regular `values.yaml`. You can use this file instead of the default one. + +- Enable replication: +```diff +- replication.enabled: false ++ replication.enabled: true +``` + +- Number of slaves replicas: +```diff +- replication.slaveReplicas: 1 ++ replication.slaveReplicas: 2 +``` + +- Set synchronous commit mode: +```diff +- replication.synchronousCommit: "off" ++ replication.synchronousCommit: "on" +``` + +- Number of replicas that will have synchronous replication: +```diff +- replication.numSynchronousReplicas: 0 ++ replication.numSynchronousReplicas: 1 +``` + +- Start a prometheus exporter: +```diff +- metrics.enabled: false ++ metrics.enabled: true +``` + +To horizontally scale this chart, you can use the `--replicas` flag to modify the number of nodes in your PostgreSQL deployment. Also you can use the `values-production.yaml` file or modify the parameters shown above. + +### Change PostgreSQL version + +To modify the PostgreSQL version used in this chart you can specify a [valid image tag](https://hub.docker.com/r/bitnami/postgresql/tags/) using the `image.tag` parameter. For example, `image.tag=12.0.0` + +### postgresql.conf / pg_hba.conf files as configMap + +This helm chart also supports to customize the whole configuration file. + +Add your custom file to "files/postgresql.conf" in your working directory. This file will be mounted as configMap to the containers and it will be used for configuring the PostgreSQL server. + +Alternatively, you can specify PostgreSQL configuration parameters using the `postgresqlConfiguration` parameter as a dict, using camelCase, e.g. {"sharedBuffers": "500MB"}. + +In addition to these options, you can also set an external ConfigMap with all the configuration files. This is done by setting the `configurationConfigMap` parameter. Note that this will override the two previous options. + +### Allow settings to be loaded from files other than the default `postgresql.conf` + +If you don't want to provide the whole PostgreSQL configuration file and only specify certain parameters, you can add your extended `.conf` files to "files/conf.d/" in your working directory. +Those files will be mounted as configMap to the containers adding/overwriting the default configuration using the `include_dir` directive that allows settings to be loaded from files other than the default `postgresql.conf`. + +Alternatively, you can also set an external ConfigMap with all the extra configuration files. This is done by setting the `extendedConfConfigMap` parameter. Note that this will override the previous option. + +### Initialize a fresh instance + +The [Bitnami PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) image allows you to use your custom scripts to initialize a fresh instance. In order to execute the scripts, they must be located inside the chart folder `files/docker-entrypoint-initdb.d` so they can be consumed as a ConfigMap. + +Alternatively, you can specify custom scripts using the `initdbScripts` parameter as dict. + +In addition to these options, you can also set an external ConfigMap with all the initialization scripts. This is done by setting the `initdbScriptsConfigMap` parameter. Note that this will override the two previous options. If your initialization scripts contain sensitive information such as credentials or passwords, you can use the `initdbScriptsSecret` parameter. + +The allowed extensions are `.sh`, `.sql` and `.sql.gz`. + +### Sidecars + +If you need additional containers to run within the same pod as PostgreSQL (e.g. an additional metrics or logging exporter), you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. + +```yaml +# For the PostgreSQL master +master: + sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +# For the PostgreSQL replicas +slave: + sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +### Metrics + +The chart optionally can start a metrics exporter for [prometheus](https://prometheus.io). The metrics endpoint (port 9187) is not exposed and it is expected that the metrics are collected from inside the k8s cluster using something similar as the described in the [example Prometheus scrape configuration](https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml). + +The exporter allows to create custom metrics from additional SQL queries. See the Chart's `values.yaml` for an example and consult the [exporters documentation](https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file) for more details. + +### Use of global variables + +In more complex scenarios, we may have the following tree of dependencies + +``` + +--------------+ + | | + +------------+ Chart 1 +-----------+ + | | | | + | --------+------+ | + | | | + | | | + | | | + | | | + v v v ++-------+------+ +--------+------+ +--------+------+ +| | | | | | +| PostgreSQL | | Sub-chart 1 | | Sub-chart 2 | +| | | | | | ++--------------+ +---------------+ +---------------+ +``` + +The three charts below depend on the parent chart Chart 1. However, subcharts 1 and 2 may need to connect to PostgreSQL as well. In order to do so, subcharts 1 and 2 need to know the PostgreSQL credentials, so one option for deploying could be deploy Chart 1 with the following parameters: + +``` +postgresql.postgresqlPassword=testtest +subchart1.postgresql.postgresqlPassword=testtest +subchart2.postgresql.postgresqlPassword=testtest +postgresql.postgresqlDatabase=db1 +subchart1.postgresql.postgresqlDatabase=db1 +subchart2.postgresql.postgresqlDatabase=db1 +``` + +If the number of dependent sub-charts increases, installing the chart with parameters can become increasingly difficult. An alternative would be to set the credentials using global variables as follows: + +``` +global.postgresql.postgresqlPassword=testtest +global.postgresql.postgresqlDatabase=db1 +``` + +This way, the credentials will be available in all of the subcharts. + +## Persistence + +The [Bitnami PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) image stores the PostgreSQL data and configurations at the `/bitnami/postgresql` path of the container. + +Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. +See the [Parameters](#parameters) section to configure the PVC or to disable persistence. + +If you already have data in it, you will fail to sync to standby nodes for all commits, details can refer to [code](https://github.com/bitnami/bitnami-docker-postgresql/blob/8725fe1d7d30ebe8d9a16e9175d05f7ad9260c93/9.6/debian-9/rootfs/libpostgresql.sh#L518-L556). If you need to use those data, please covert them to sql and import after `helm install` finished. + +## NetworkPolicy + +To enable network policy for PostgreSQL, install [a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), and set `networkPolicy.enabled` to `true`. + +For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting the DefaultDeny namespace annotation. Note: this will enforce policy for _all_ pods in the namespace: + +```console +$ kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" +``` + +With NetworkPolicy enabled, traffic will be limited to just port 5432. + +For more precise policy, set `networkPolicy.allowExternal=false`. This will only allow pods with the generated client label to connect to PostgreSQL. +This label will be displayed in the output of a successful install. + +## Differences between Bitnami PostgreSQL image and [Docker Official](https://hub.docker.com/_/postgres) image + +- The Docker Official PostgreSQL image does not support replication. If you pass any replication environment variable, this would be ignored. The only environment variables supported by the Docker Official image are POSTGRES_USER, POSTGRES_DB, POSTGRES_PASSWORD, POSTGRES_INITDB_ARGS, POSTGRES_INITDB_WALDIR and PGDATA. All the remaining environment variables are specific to the Bitnami PostgreSQL image. +- The Bitnami PostgreSQL image is non-root by default. This requires that you run the pod with `securityContext` and updates the permissions of the volume with an `initContainer`. A key benefit of this configuration is that the pod follows security best practices and is prepared to run on Kubernetes distributions with hard security constraints like OpenShift. +- For OpenShift, one may either define the runAsUser and fsGroup accordingly, or try this more dynamic option: volumePermissions.securityContext.runAsUser="auto",securityContext.enabled=false,shmVolume.chmod.enabled=false + +### Deploy chart using Docker Official PostgreSQL Image + +From chart version 4.0.0, it is possible to use this chart with the Docker Official PostgreSQL image. +Besides specifying the new Docker repository and tag, it is important to modify the PostgreSQL data directory and volume mount point. Basically, the PostgreSQL data dir cannot be the mount point directly, it has to be a subdirectory. + +``` +helm install postgres \ + --set image.repository=postgres \ + --set image.tag=10.6 \ + --set postgresqlDataDir=/data/pgdata \ + --set persistence.mountPath=/data/ \ + stable/postgresql +``` + +## Upgrade + +It's necessary to specify the existing passwords while performing an upgrade to ensure the secrets are not updated with invalid randomly generated passwords. Remember to specify the existing values of the `postgresqlPassword` and `replication.password` parameters when upgrading the chart: + +```bash +$ helm upgrade my-release bitnami/influxdb \ + --set postgresqlPassword=[POSTGRESQL_PASSWORD] \ + --set replication.password=[REPLICATION_PASSWORD] +``` + +> Note: you need to substitute the placeholders _[POSTGRESQL_PASSWORD]_, and _[REPLICATION_PASSWORD]_ with the values obtained from instructions in the installation notes. + +## 8.0.0 + +Prefixes the port names with their protocols to comply with Istio conventions. + +If you depend on the port names in your setup, make sure to update them to reflect this change. + +## 7.1.0 + +Adds support for LDAP configuration. + +## 7.0.0 + +Helm performs a lookup for the object based on its group (apps), version (v1), and kind (Deployment). Also known as its GroupVersionKind, or GVK. Changing the GVK is considered a compatibility breaker from Kubernetes' point of view, so you cannot "upgrade" those objects to the new GVK in-place. Earlier versions of Helm 3 did not perform the lookup correctly which has since been fixed to match the spec. + +In https://github.com/helm/charts/pull/17281 the `apiVersion` of the statefulset resources was updated to `apps/v1` in tune with the api's deprecated, resulting in compatibility breakage. + +This major version bump signifies this change. + +## 6.5.7 + +In this version, the chart will use PostgreSQL with the Postgis extension included. The version used with Postgresql version 10, 11 and 12 is Postgis 2.5. It has been compiled with the following dependencies: + + - protobuf + - protobuf-c + - json-c + - geos + - proj + +## 5.0.0 + +In this version, the **chart is using PostgreSQL 11 instead of PostgreSQL 10**. You can find the main difference and notable changes in the following links: [https://www.postgresql.org/about/news/1894/](https://www.postgresql.org/about/news/1894/) and [https://www.postgresql.org/about/featurematrix/](https://www.postgresql.org/about/featurematrix/). + +For major releases of PostgreSQL, the internal data storage format is subject to change, thus complicating upgrades, you can see some errors like the following one in the logs: + +```bash +Welcome to the Bitnami postgresql container +Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-postgresql +Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-postgresql/issues +Send us your feedback at containers@bitnami.com + +INFO ==> ** Starting PostgreSQL setup ** +NFO ==> Validating settings in POSTGRESQL_* env vars.. +INFO ==> Initializing PostgreSQL database... +INFO ==> postgresql.conf file not detected. Generating it... +INFO ==> pg_hba.conf file not detected. Generating it... +INFO ==> Deploying PostgreSQL with persisted data... +INFO ==> Configuring replication parameters +INFO ==> Loading custom scripts... +INFO ==> Enabling remote connections +INFO ==> Stopping PostgreSQL... +INFO ==> ** PostgreSQL setup finished! ** + +INFO ==> ** Starting PostgreSQL ** + [1] FATAL: database files are incompatible with server + [1] DETAIL: The data directory was initialized by PostgreSQL version 10, which is not compatible with this version 11.3. +``` +In this case, you should migrate the data from the old chart to the new one following an approach similar to that described in [this section](https://www.postgresql.org/docs/current/upgrading.html#UPGRADING-VIA-PGDUMPALL) from the official documentation. Basically, create a database dump in the old chart, move and restore it in the new one. + +### 4.0.0 + +This chart will use by default the Bitnami PostgreSQL container starting from version `10.7.0-r68`. This version moves the initialization logic from node.js to bash. This new version of the chart requires setting the `POSTGRES_PASSWORD` in the slaves as well, in order to properly configure the `pg_hba.conf` file. Users from previous versions of the chart are advised to upgrade immediately. + +IMPORTANT: If you do not want to upgrade the chart version then make sure you use the `10.7.0-r68` version of the container. Otherwise, you will get this error + +``` +The POSTGRESQL_PASSWORD environment variable is empty or not set. Set the environment variable ALLOW_EMPTY_PASSWORD=yes to allow the container to be started with blank passwords. This is recommended only for development +``` + +### 3.0.0 + +This releases make it possible to specify different nodeSelector, affinity and tolerations for master and slave pods. +It also fixes an issue with `postgresql.master.fullname` helper template not obeying fullnameOverride. + +#### Breaking changes + +- `affinty` has been renamed to `master.affinity` and `slave.affinity`. +- `tolerations` has been renamed to `master.tolerations` and `slave.tolerations`. +- `nodeSelector` has been renamed to `master.nodeSelector` and `slave.nodeSelector`. + +### 2.0.0 + +In order to upgrade from the `0.X.X` branch to `1.X.X`, you should follow the below steps: + + - Obtain the service name (`SERVICE_NAME`) and password (`OLD_PASSWORD`) of the existing postgresql chart. You can find the instructions to obtain the password in the NOTES.txt, the service name can be obtained by running + + ```console +$ kubectl get svc + ``` + +- Install (not upgrade) the new version + +```console +$ helm repo update +$ helm install my-release stable/postgresql +``` + +- Connect to the new pod (you can obtain the name by running `kubectl get pods`): + +```console +$ kubectl exec -it NAME bash +``` + +- Once logged in, create a dump file from the previous database using `pg_dump`, for that we should connect to the previous postgresql chart: + +```console +$ pg_dump -h SERVICE_NAME -U postgres DATABASE_NAME > /tmp/backup.sql +``` + +After run above command you should be prompted for a password, this password is the previous chart password (`OLD_PASSWORD`). +This operation could take some time depending on the database size. + +- Once you have the backup file, you can restore it with a command like the one below: + +```console +$ psql -U postgres DATABASE_NAME < /tmp/backup.sql +``` + +In this case, you are accessing to the local postgresql, so the password should be the new one (you can find it in NOTES.txt). + +If you want to restore the database and the database schema does not exist, it is necessary to first follow the steps described below. + +```console +$ psql -U postgres +postgres=# drop database DATABASE_NAME; +postgres=# create database DATABASE_NAME; +postgres=# create user USER_NAME; +postgres=# alter role USER_NAME with password 'BITNAMI_USER_PASSWORD'; +postgres=# grant all privileges on database DATABASE_NAME to USER_NAME; +postgres=# alter database DATABASE_NAME owner to USER_NAME; +``` diff --git a/infra/charts/feast/charts/prometheus-statsd-exporter/README.md b/infra/charts/feast/charts/prometheus-statsd-exporter/README.md index af91750df81..8a6739f393b 100644 --- a/infra/charts/feast/charts/prometheus-statsd-exporter/README.md +++ b/infra/charts/feast/charts/prometheus-statsd-exporter/README.md @@ -1,49 +1,57 @@ -prometheus-statsd-exporter -========================== -A Helm chart for prometheus statsd-exporter Scrape metrics stored statsd - -Current chart version is `0.1.2` - -Source code can be found [here](https://github.com/prometheus/statsd_exporter) - - - -## Chart Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.repository | string | `"prom/statsd-exporter"` | | -| image.tag | string | `"v0.12.1"` | | -| persistentVolume.accessModes[0] | string | `"ReadWriteOnce"` | | -| persistentVolume.annotations | object | `{}` | | -| persistentVolume.claimName | string | `"prometheus-statsd-exporter"` | | -| persistentVolume.enabled | bool | `true` | | -| persistentVolume.existingClaim | string | `""` | | -| persistentVolume.mountPath | string | `"/data"` | | -| persistentVolume.name | string | `"storage-volume"` | | -| persistentVolume.size | string | `"20Gi"` | | -| persistentVolume.storageClass | object | `{}` | | -| persistentVolume.subPath | string | `""` | | -| service.annotations | object | `{}` | | -| service.clusterIP | string | `""` | | -| service.externalIPs | list | `[]` | | -| service.labels | object | `{}` | | -| service.loadBalancerIP | string | `""` | | -| service.loadBalancerSourceRanges | list | `[]` | | -| service.metricsPort | int | `9102` | | -| service.servicePort | int | `80` | | -| service.statsdPort | int | `9125` | | -| service.type | string | `"ClusterIP"` | | -| serviceAccount.componentName | string | `"prometheus-statsd-exporter"` | | -| serviceAccount.enable | bool | `false` | | -| statsdexporter.affinity | object | `{}` | | -| statsdexporter.extraArgs | object | `{}` | | -| statsdexporter.ingress.enabled | bool | `false` | | -| statsdexporter.nodeSelector | object | `{}` | | -| statsdexporter.podAnnotations."prometheus.io/path" | string | `"/metrics"` | | -| statsdexporter.podAnnotations."prometheus.io/port" | string | `"9102"` | | -| statsdexporter.podAnnotations."prometheus.io/scrape" | string | `"true"` | | -| statsdexporter.replicaCount | int | `1` | | -| statsdexporter.resources | object | `{}` | | -| statsdexporter.tolerations | object | `{}` | | +# Prometheus statsd-exporter + + ## TL;DR; + + ```console +$ helm install incubator/prometheus-statsd-exporter +``` + + ## Introduction + + This chart bootstraps a prometheus-statsd-exporter deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + ## Installing the Chart + + To install the chart with the release name `my-release`: + + ```console +$ helm install incubator/prometheus-statsd-exporter --name my-release +``` + + + The command deploys prometheus-statsd-exporter on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + + ## Uninstalling the Chart + + To uninstall/delete the `my-release` deployment: + + ```console +$ helm delete my-release +``` + + The command removes all the Kubernetes components associated with the chart and deletes the release. + + ## Configuration + +|Parameter | Description | Default | +|----------------------------|------------------------------------------------------|----------------------------------------| +|`extraArgs` | key:value list of extra arguments to give the binary | `{}` | +|`image.pullPolicy` | Image pull policy | `IfNotPresent` | +|`image.repository` | Image repository | `prom/statsd-exporter` | +|`image.tag` | Image tag | `v0.8.0` | +|`ingress.enabled` | enable ingress | `false` | +|`ingress.path` | ingress base path | `/` | +|`ingress.host` | Ingress accepted hostnames | `nil` | +|`ingress.tls` | Ingress TLS configuration | `[]` | +|`ingress.annotations` | Ingress annotations | `{}` | +|`service.type` | type of service | `ClusterIP` | +|`tolerations` | List of node taints to tolerate | `[]` | +|`resources` | pod resource requests & limits | `{}` | +| `persistence.enabled` | Create a volume to store data | true | + + Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + + ```console +$ helm install incubator/prometheus-statsd-exporter --name my-release -f values.yaml +``` +> **Tip**: You can use the default [values.yaml](values.yaml) \ No newline at end of file diff --git a/infra/charts/feast/charts/prometheus/README.md b/infra/charts/feast/charts/prometheus/README.md index ff42598cb0f..dc32dcd15a8 100644 --- a/infra/charts/feast/charts/prometheus/README.md +++ b/infra/charts/feast/charts/prometheus/README.md @@ -1,448 +1,471 @@ -prometheus -========== -Prometheus is a monitoring system and time series database. - -Current chart version is `11.0.2` - -Source code can be found [here](https://prometheus.io/) - -## Chart Requirements - -| Repository | Name | Version | -|------------|------|---------| -| https://kubernetes-charts.storage.googleapis.com/ | kube-state-metrics | 2.7.* | - -## Chart Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| alertRelabelConfigs | string | `nil` | | -| alertmanager.affinity | object | `{}` | | -| alertmanager.baseURL | string | `"http://localhost:9093"` | | -| alertmanager.configFileName | string | `"alertmanager.yml"` | | -| alertmanager.configFromSecret | string | `""` | | -| alertmanager.configMapOverrideName | string | `""` | | -| alertmanager.enabled | bool | `true` | | -| alertmanager.extraArgs | object | `{}` | | -| alertmanager.extraEnv | object | `{}` | | -| alertmanager.extraSecretMounts | list | `[]` | | -| alertmanager.image.pullPolicy | string | `"IfNotPresent"` | | -| alertmanager.image.repository | string | `"prom/alertmanager"` | | -| alertmanager.image.tag | string | `"v0.20.0"` | | -| alertmanager.ingress.annotations | object | `{}` | | -| alertmanager.ingress.enabled | bool | `false` | | -| alertmanager.ingress.extraLabels | object | `{}` | | -| alertmanager.ingress.extraPaths | list | `[]` | | -| alertmanager.ingress.hosts | list | `[]` | | -| alertmanager.ingress.tls | list | `[]` | | -| alertmanager.name | string | `"alertmanager"` | | -| alertmanager.nodeSelector | object | `{}` | | -| alertmanager.persistentVolume.accessModes[0] | string | `"ReadWriteOnce"` | | -| alertmanager.persistentVolume.annotations | object | `{}` | | -| alertmanager.persistentVolume.enabled | bool | `true` | | -| alertmanager.persistentVolume.existingClaim | string | `""` | | -| alertmanager.persistentVolume.mountPath | string | `"/data"` | | -| alertmanager.persistentVolume.size | string | `"2Gi"` | | -| alertmanager.persistentVolume.subPath | string | `""` | | -| alertmanager.podAnnotations | object | `{}` | | -| alertmanager.podDisruptionBudget.enabled | bool | `false` | | -| alertmanager.podDisruptionBudget.maxUnavailable | int | `1` | | -| alertmanager.podLabels | object | `{}` | | -| alertmanager.podSecurityPolicy.annotations | object | `{}` | | -| alertmanager.prefixURL | string | `""` | | -| alertmanager.priorityClassName | string | `""` | | -| alertmanager.replicaCount | int | `1` | | -| alertmanager.resources | object | `{}` | | -| alertmanager.securityContext.fsGroup | int | `65534` | | -| alertmanager.securityContext.runAsGroup | int | `65534` | | -| alertmanager.securityContext.runAsNonRoot | bool | `true` | | -| alertmanager.securityContext.runAsUser | int | `65534` | | -| alertmanager.service.annotations | object | `{}` | | -| alertmanager.service.clusterIP | string | `""` | | -| alertmanager.service.externalIPs | list | `[]` | | -| alertmanager.service.labels | object | `{}` | | -| alertmanager.service.loadBalancerIP | string | `""` | | -| alertmanager.service.loadBalancerSourceRanges | list | `[]` | | -| alertmanager.service.servicePort | int | `80` | | -| alertmanager.service.sessionAffinity | string | `"None"` | | -| alertmanager.service.type | string | `"ClusterIP"` | | -| alertmanager.statefulSet.enabled | bool | `false` | | -| alertmanager.statefulSet.headless.annotations | object | `{}` | | -| alertmanager.statefulSet.headless.labels | object | `{}` | | -| alertmanager.statefulSet.headless.servicePort | int | `80` | | -| alertmanager.statefulSet.podManagementPolicy | string | `"OrderedReady"` | | -| alertmanager.tolerations | list | `[]` | | -| alertmanagerFiles."alertmanager.yml".global | object | `{}` | | -| alertmanagerFiles."alertmanager.yml".receivers[0].name | string | `"default-receiver"` | | -| alertmanagerFiles."alertmanager.yml".route.group_interval | string | `"5m"` | | -| alertmanagerFiles."alertmanager.yml".route.group_wait | string | `"10s"` | | -| alertmanagerFiles."alertmanager.yml".route.receiver | string | `"default-receiver"` | | -| alertmanagerFiles."alertmanager.yml".route.repeat_interval | string | `"3h"` | | -| configmapReload.alertmanager.enabled | bool | `true` | | -| configmapReload.alertmanager.extraArgs | object | `{}` | | -| configmapReload.alertmanager.extraConfigmapMounts | list | `[]` | | -| configmapReload.alertmanager.extraVolumeDirs | list | `[]` | | -| configmapReload.alertmanager.image.pullPolicy | string | `"IfNotPresent"` | | -| configmapReload.alertmanager.image.repository | string | `"jimmidyson/configmap-reload"` | | -| configmapReload.alertmanager.image.tag | string | `"v0.3.0"` | | -| configmapReload.alertmanager.name | string | `"configmap-reload"` | | -| configmapReload.alertmanager.resources | object | `{}` | | -| configmapReload.prometheus.enabled | bool | `true` | | -| configmapReload.prometheus.extraArgs | object | `{}` | | -| configmapReload.prometheus.extraConfigmapMounts | list | `[]` | | -| configmapReload.prometheus.extraVolumeDirs | list | `[]` | | -| configmapReload.prometheus.image.pullPolicy | string | `"IfNotPresent"` | | -| configmapReload.prometheus.image.repository | string | `"jimmidyson/configmap-reload"` | | -| configmapReload.prometheus.image.tag | string | `"v0.3.0"` | | -| configmapReload.prometheus.name | string | `"configmap-reload"` | | -| configmapReload.prometheus.resources | object | `{}` | | -| extraScrapeConfigs | string | `nil` | | -| imagePullSecrets | string | `nil` | | -| kubeStateMetrics.enabled | bool | `true` | | -| networkPolicy.enabled | bool | `false` | | -| nodeExporter.enabled | bool | `false` | | -| nodeExporter.extraArgs | object | `{}` | | -| nodeExporter.extraConfigmapMounts | list | `[]` | | -| nodeExporter.extraHostPathMounts | list | `[]` | | -| nodeExporter.hostNetwork | bool | `true` | | -| nodeExporter.hostPID | bool | `true` | | -| nodeExporter.image.pullPolicy | string | `"IfNotPresent"` | | -| nodeExporter.image.repository | string | `"prom/node-exporter"` | | -| nodeExporter.image.tag | string | `"v0.18.1"` | | -| nodeExporter.name | string | `"node-exporter"` | | -| nodeExporter.nodeSelector | object | `{}` | | -| nodeExporter.pod.labels | object | `{}` | | -| nodeExporter.podAnnotations | object | `{}` | | -| nodeExporter.podDisruptionBudget.enabled | bool | `false` | | -| nodeExporter.podDisruptionBudget.maxUnavailable | int | `1` | | -| nodeExporter.podSecurityPolicy.annotations | object | `{}` | | -| nodeExporter.priorityClassName | string | `""` | | -| nodeExporter.resources | object | `{}` | | -| nodeExporter.securityContext | object | `{}` | | -| nodeExporter.service.annotations."prometheus.io/scrape" | string | `"true"` | | -| nodeExporter.service.clusterIP | string | `"None"` | | -| nodeExporter.service.externalIPs | list | `[]` | | -| nodeExporter.service.hostPort | int | `9100` | | -| nodeExporter.service.labels | object | `{}` | | -| nodeExporter.service.loadBalancerIP | string | `""` | | -| nodeExporter.service.loadBalancerSourceRanges | list | `[]` | | -| nodeExporter.service.servicePort | int | `9100` | | -| nodeExporter.service.type | string | `"ClusterIP"` | | -| nodeExporter.tolerations | list | `[]` | | -| nodeExporter.updateStrategy.type | string | `"RollingUpdate"` | | -| podSecurityPolicy.enabled | bool | `false` | | -| pushgateway.enabled | bool | `true` | | -| pushgateway.extraArgs | object | `{}` | | -| pushgateway.image.pullPolicy | string | `"IfNotPresent"` | | -| pushgateway.image.repository | string | `"prom/pushgateway"` | | -| pushgateway.image.tag | string | `"v1.0.1"` | | -| pushgateway.ingress.annotations | object | `{}` | | -| pushgateway.ingress.enabled | bool | `false` | | -| pushgateway.ingress.extraPaths | list | `[]` | | -| pushgateway.ingress.hosts | list | `[]` | | -| pushgateway.ingress.tls | list | `[]` | | -| pushgateway.name | string | `"pushgateway"` | | -| pushgateway.nodeSelector | object | `{}` | | -| pushgateway.persistentVolume.accessModes[0] | string | `"ReadWriteOnce"` | | -| pushgateway.persistentVolume.annotations | object | `{}` | | -| pushgateway.persistentVolume.enabled | bool | `false` | | -| pushgateway.persistentVolume.existingClaim | string | `""` | | -| pushgateway.persistentVolume.mountPath | string | `"/data"` | | -| pushgateway.persistentVolume.size | string | `"2Gi"` | | -| pushgateway.persistentVolume.subPath | string | `""` | | -| pushgateway.podAnnotations | object | `{}` | | -| pushgateway.podDisruptionBudget.enabled | bool | `false` | | -| pushgateway.podDisruptionBudget.maxUnavailable | int | `1` | | -| pushgateway.podSecurityPolicy.annotations | object | `{}` | | -| pushgateway.priorityClassName | string | `""` | | -| pushgateway.replicaCount | int | `1` | | -| pushgateway.resources | object | `{}` | | -| pushgateway.securityContext.runAsNonRoot | bool | `true` | | -| pushgateway.securityContext.runAsUser | int | `65534` | | -| pushgateway.service.annotations."prometheus.io/probe" | string | `"pushgateway"` | | -| pushgateway.service.clusterIP | string | `""` | | -| pushgateway.service.externalIPs | list | `[]` | | -| pushgateway.service.labels | object | `{}` | | -| pushgateway.service.loadBalancerIP | string | `""` | | -| pushgateway.service.loadBalancerSourceRanges | list | `[]` | | -| pushgateway.service.servicePort | int | `9091` | | -| pushgateway.service.type | string | `"ClusterIP"` | | -| pushgateway.tolerations | list | `[]` | | -| rbac.create | bool | `true` | | -| server.affinity | object | `{}` | | -| server.alertmanagers | list | `[]` | | -| server.baseURL | string | `""` | | -| server.configMapOverrideName | string | `""` | | -| server.configPath | string | `"/etc/config/prometheus.yml"` | | -| server.emptyDir.sizeLimit | string | `""` | | -| server.enabled | bool | `true` | | -| server.env | list | `[]` | | -| server.extraArgs | object | `{}` | | -| server.extraConfigmapMounts | list | `[]` | | -| server.extraFlags[0] | string | `"web.enable-lifecycle"` | | -| server.extraHostPathMounts | list | `[]` | | -| server.extraInitContainers | list | `[]` | | -| server.extraSecretMounts | list | `[]` | | -| server.extraVolumeMounts | list | `[]` | | -| server.extraVolumes | list | `[]` | | -| server.global.evaluation_interval | string | `"1m"` | | -| server.global.scrape_interval | string | `"1m"` | | -| server.global.scrape_timeout | string | `"10s"` | | -| server.image.pullPolicy | string | `"IfNotPresent"` | | -| server.image.repository | string | `"prom/prometheus"` | | -| server.image.tag | string | `"v2.16.0"` | | -| server.ingress.annotations | object | `{}` | | -| server.ingress.enabled | bool | `false` | | -| server.ingress.extraLabels | object | `{}` | | -| server.ingress.extraPaths | list | `[]` | | -| server.ingress.hosts | list | `[]` | | -| server.ingress.tls | list | `[]` | | -| server.livenessProbeFailureThreshold | int | `3` | | -| server.livenessProbeInitialDelay | int | `30` | | -| server.livenessProbeSuccessThreshold | int | `1` | | -| server.livenessProbeTimeout | int | `30` | | -| server.name | string | `"server"` | | -| server.nodeSelector | object | `{}` | | -| server.persistentVolume.accessModes[0] | string | `"ReadWriteOnce"` | | -| server.persistentVolume.annotations | object | `{}` | | -| server.persistentVolume.enabled | bool | `true` | | -| server.persistentVolume.existingClaim | string | `""` | | -| server.persistentVolume.mountPath | string | `"/data"` | | -| server.persistentVolume.size | string | `"8Gi"` | | -| server.persistentVolume.subPath | string | `""` | | -| server.podAnnotations | object | `{}` | | -| server.podDisruptionBudget.enabled | bool | `false` | | -| server.podDisruptionBudget.maxUnavailable | int | `1` | | -| server.podLabels | object | `{}` | | -| server.podSecurityPolicy.annotations | object | `{}` | | -| server.prefixURL | string | `""` | | -| server.priorityClassName | string | `""` | | -| server.readinessProbeFailureThreshold | int | `3` | | -| server.readinessProbeInitialDelay | int | `30` | | -| server.readinessProbeSuccessThreshold | int | `1` | | -| server.readinessProbeTimeout | int | `30` | | -| server.remoteRead | object | `{}` | | -| server.remoteWrite | object | `{}` | | -| server.replicaCount | int | `1` | | -| server.resources | object | `{}` | | -| server.retention | string | `"15d"` | | -| server.securityContext.fsGroup | int | `65534` | | -| server.securityContext.runAsGroup | int | `65534` | | -| server.securityContext.runAsNonRoot | bool | `true` | | -| server.securityContext.runAsUser | int | `65534` | | -| server.service.annotations | object | `{}` | | -| server.service.clusterIP | string | `""` | | -| server.service.externalIPs | list | `[]` | | -| server.service.gRPC.enabled | bool | `false` | | -| server.service.gRPC.servicePort | int | `10901` | | -| server.service.labels | object | `{}` | | -| server.service.loadBalancerIP | string | `""` | | -| server.service.loadBalancerSourceRanges | list | `[]` | | -| server.service.servicePort | int | `80` | | -| server.service.sessionAffinity | string | `"None"` | | -| server.service.statefulsetReplica.enabled | bool | `false` | | -| server.service.statefulsetReplica.replica | int | `0` | | -| server.service.type | string | `"ClusterIP"` | | -| server.sidecarContainers | string | `nil` | | -| server.statefulSet.annotations | object | `{}` | | -| server.statefulSet.enabled | bool | `false` | | -| server.statefulSet.headless.annotations | object | `{}` | | -| server.statefulSet.headless.labels | object | `{}` | | -| server.statefulSet.headless.servicePort | int | `80` | | -| server.statefulSet.labels | object | `{}` | | -| server.statefulSet.podManagementPolicy | string | `"OrderedReady"` | | -| server.terminationGracePeriodSeconds | int | `300` | | -| server.tolerations | list | `[]` | | -| server.verticalAutoscaler.enabled | bool | `false` | | -| serverFiles."alerting_rules.yml" | object | `{}` | | -| serverFiles."prometheus.yml".rule_files[0] | string | `"/etc/config/recording_rules.yml"` | | -| serverFiles."prometheus.yml".rule_files[1] | string | `"/etc/config/alerting_rules.yml"` | | -| serverFiles."prometheus.yml".rule_files[2] | string | `"/etc/config/rules"` | | -| serverFiles."prometheus.yml".rule_files[3] | string | `"/etc/config/alerts"` | | -| serverFiles."prometheus.yml".scrape_configs[0].job_name | string | `"prometheus"` | | -| serverFiles."prometheus.yml".scrape_configs[0].static_configs[0].targets[0] | string | `"localhost:9090"` | | -| serverFiles."prometheus.yml".scrape_configs[1].bearer_token_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | | -| serverFiles."prometheus.yml".scrape_configs[1].job_name | string | `"kubernetes-apiservers"` | | -| serverFiles."prometheus.yml".scrape_configs[1].kubernetes_sd_configs[0].role | string | `"endpoints"` | | -| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].action | string | `"keep"` | | -| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].regex | string | `"default;kubernetes;https"` | | -| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].source_labels[1] | string | `"__meta_kubernetes_service_name"` | | -| serverFiles."prometheus.yml".scrape_configs[1].relabel_configs[0].source_labels[2] | string | `"__meta_kubernetes_endpoint_port_name"` | | -| serverFiles."prometheus.yml".scrape_configs[1].scheme | string | `"https"` | | -| serverFiles."prometheus.yml".scrape_configs[1].tls_config.ca_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"` | | -| serverFiles."prometheus.yml".scrape_configs[1].tls_config.insecure_skip_verify | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[2].bearer_token_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | | -| serverFiles."prometheus.yml".scrape_configs[2].job_name | string | `"kubernetes-nodes"` | | -| serverFiles."prometheus.yml".scrape_configs[2].kubernetes_sd_configs[0].role | string | `"node"` | | -| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[0].action | string | `"labelmap"` | | -| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[0].regex | string | `"__meta_kubernetes_node_label_(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[1].replacement | string | `"kubernetes.default.svc:443"` | | -| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[1].target_label | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[2].regex | string | `"(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[2].replacement | string | `"/api/v1/nodes/$1/proxy/metrics"` | | -| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[2].source_labels[0] | string | `"__meta_kubernetes_node_name"` | | -| serverFiles."prometheus.yml".scrape_configs[2].relabel_configs[2].target_label | string | `"__metrics_path__"` | | -| serverFiles."prometheus.yml".scrape_configs[2].scheme | string | `"https"` | | -| serverFiles."prometheus.yml".scrape_configs[2].tls_config.ca_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"` | | -| serverFiles."prometheus.yml".scrape_configs[2].tls_config.insecure_skip_verify | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[3].bearer_token_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | | -| serverFiles."prometheus.yml".scrape_configs[3].job_name | string | `"kubernetes-nodes-cadvisor"` | | -| serverFiles."prometheus.yml".scrape_configs[3].kubernetes_sd_configs[0].role | string | `"node"` | | -| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[0].action | string | `"labelmap"` | | -| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[0].regex | string | `"__meta_kubernetes_node_label_(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[1].replacement | string | `"kubernetes.default.svc:443"` | | -| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[1].target_label | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[2].regex | string | `"(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[2].replacement | string | `"/api/v1/nodes/$1/proxy/metrics/cadvisor"` | | -| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[2].source_labels[0] | string | `"__meta_kubernetes_node_name"` | | -| serverFiles."prometheus.yml".scrape_configs[3].relabel_configs[2].target_label | string | `"__metrics_path__"` | | -| serverFiles."prometheus.yml".scrape_configs[3].scheme | string | `"https"` | | -| serverFiles."prometheus.yml".scrape_configs[3].tls_config.ca_file | string | `"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"` | | -| serverFiles."prometheus.yml".scrape_configs[3].tls_config.insecure_skip_verify | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[4].job_name | string | `"kubernetes-service-endpoints"` | | -| serverFiles."prometheus.yml".scrape_configs[4].kubernetes_sd_configs[0].role | string | `"endpoints"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[0].action | string | `"keep"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[0].regex | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_scrape"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[1].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[1].regex | string | `"(https?)"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[1].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_scheme"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[1].target_label | string | `"__scheme__"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[2].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[2].regex | string | `"(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[2].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_path"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[2].target_label | string | `"__metrics_path__"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].regex | string | `"([^:]+)(?::\\d+)?;(\\d+)"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].replacement | string | `"$1:$2"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].source_labels[0] | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].source_labels[1] | string | `"__meta_kubernetes_service_annotation_prometheus_io_port"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[3].target_label | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[4].action | string | `"labelmap"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[4].regex | string | `"__meta_kubernetes_service_label_(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[5].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[5].target_label | string | `"kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[6].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[6].source_labels[0] | string | `"__meta_kubernetes_service_name"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[6].target_label | string | `"kubernetes_name"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[7].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[7].source_labels[0] | string | `"__meta_kubernetes_pod_node_name"` | | -| serverFiles."prometheus.yml".scrape_configs[4].relabel_configs[7].target_label | string | `"kubernetes_node"` | | -| serverFiles."prometheus.yml".scrape_configs[5].job_name | string | `"kubernetes-service-endpoints-slow"` | | -| serverFiles."prometheus.yml".scrape_configs[5].kubernetes_sd_configs[0].role | string | `"endpoints"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[0].action | string | `"keep"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[0].regex | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_scrape_slow"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[1].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[1].regex | string | `"(https?)"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[1].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_scheme"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[1].target_label | string | `"__scheme__"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[2].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[2].regex | string | `"(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[2].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_path"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[2].target_label | string | `"__metrics_path__"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].regex | string | `"([^:]+)(?::\\d+)?;(\\d+)"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].replacement | string | `"$1:$2"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].source_labels[0] | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].source_labels[1] | string | `"__meta_kubernetes_service_annotation_prometheus_io_port"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[3].target_label | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[4].action | string | `"labelmap"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[4].regex | string | `"__meta_kubernetes_service_label_(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[5].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[5].target_label | string | `"kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[6].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[6].source_labels[0] | string | `"__meta_kubernetes_service_name"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[6].target_label | string | `"kubernetes_name"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[7].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[7].source_labels[0] | string | `"__meta_kubernetes_pod_node_name"` | | -| serverFiles."prometheus.yml".scrape_configs[5].relabel_configs[7].target_label | string | `"kubernetes_node"` | | -| serverFiles."prometheus.yml".scrape_configs[5].scrape_interval | string | `"5m"` | | -| serverFiles."prometheus.yml".scrape_configs[5].scrape_timeout | string | `"30s"` | | -| serverFiles."prometheus.yml".scrape_configs[6].honor_labels | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[6].job_name | string | `"prometheus-pushgateway"` | | -| serverFiles."prometheus.yml".scrape_configs[6].kubernetes_sd_configs[0].role | string | `"service"` | | -| serverFiles."prometheus.yml".scrape_configs[6].relabel_configs[0].action | string | `"keep"` | | -| serverFiles."prometheus.yml".scrape_configs[6].relabel_configs[0].regex | string | `"pushgateway"` | | -| serverFiles."prometheus.yml".scrape_configs[6].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_probe"` | | -| serverFiles."prometheus.yml".scrape_configs[7].job_name | string | `"kubernetes-services"` | | -| serverFiles."prometheus.yml".scrape_configs[7].kubernetes_sd_configs[0].role | string | `"service"` | | -| serverFiles."prometheus.yml".scrape_configs[7].metrics_path | string | `"/probe"` | | -| serverFiles."prometheus.yml".scrape_configs[7].params.module[0] | string | `"http_2xx"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[0].action | string | `"keep"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[0].regex | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_service_annotation_prometheus_io_probe"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[1].source_labels[0] | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[1].target_label | string | `"__param_target"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[2].replacement | string | `"blackbox"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[2].target_label | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[3].source_labels[0] | string | `"__param_target"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[3].target_label | string | `"instance"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[4].action | string | `"labelmap"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[4].regex | string | `"__meta_kubernetes_service_label_(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[5].target_label | string | `"kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[6].source_labels[0] | string | `"__meta_kubernetes_service_name"` | | -| serverFiles."prometheus.yml".scrape_configs[7].relabel_configs[6].target_label | string | `"kubernetes_name"` | | -| serverFiles."prometheus.yml".scrape_configs[8].job_name | string | `"kubernetes-pods"` | | -| serverFiles."prometheus.yml".scrape_configs[8].kubernetes_sd_configs[0].role | string | `"pod"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[0].action | string | `"keep"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[0].regex | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_scrape"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[1].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[1].regex | string | `"(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[1].source_labels[0] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_path"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[1].target_label | string | `"__metrics_path__"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].regex | string | `"([^:]+)(?::\\d+)?;(\\d+)"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].replacement | string | `"$1:$2"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].source_labels[0] | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].source_labels[1] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_port"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[2].target_label | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[3].action | string | `"labelmap"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[3].regex | string | `"__meta_kubernetes_pod_label_(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[4].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[4].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[4].target_label | string | `"kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[5].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_pod_name"` | | -| serverFiles."prometheus.yml".scrape_configs[8].relabel_configs[5].target_label | string | `"kubernetes_pod_name"` | | -| serverFiles."prometheus.yml".scrape_configs[9].job_name | string | `"kubernetes-pods-slow"` | | -| serverFiles."prometheus.yml".scrape_configs[9].kubernetes_sd_configs[0].role | string | `"pod"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[0].action | string | `"keep"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[0].regex | bool | `true` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[0].source_labels[0] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_scrape_slow"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[1].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[1].regex | string | `"(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[1].source_labels[0] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_path"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[1].target_label | string | `"__metrics_path__"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].regex | string | `"([^:]+)(?::\\d+)?;(\\d+)"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].replacement | string | `"$1:$2"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].source_labels[0] | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].source_labels[1] | string | `"__meta_kubernetes_pod_annotation_prometheus_io_port"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[2].target_label | string | `"__address__"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[3].action | string | `"labelmap"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[3].regex | string | `"__meta_kubernetes_pod_label_(.+)"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[4].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[4].source_labels[0] | string | `"__meta_kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[4].target_label | string | `"kubernetes_namespace"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[5].action | string | `"replace"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[5].source_labels[0] | string | `"__meta_kubernetes_pod_name"` | | -| serverFiles."prometheus.yml".scrape_configs[9].relabel_configs[5].target_label | string | `"kubernetes_pod_name"` | | -| serverFiles."prometheus.yml".scrape_configs[9].scrape_interval | string | `"5m"` | | -| serverFiles."prometheus.yml".scrape_configs[9].scrape_timeout | string | `"30s"` | | -| serverFiles."recording_rules.yml" | object | `{}` | | -| serverFiles.alerts | object | `{}` | | -| serverFiles.rules | object | `{}` | | -| serviceAccounts.alertmanager.create | bool | `true` | | -| serviceAccounts.alertmanager.name | string | `nil` | | -| serviceAccounts.nodeExporter.create | bool | `true` | | -| serviceAccounts.nodeExporter.name | string | `nil` | | -| serviceAccounts.pushgateway.create | bool | `true` | | -| serviceAccounts.pushgateway.name | string | `nil` | | -| serviceAccounts.server.create | bool | `true` | | -| serviceAccounts.server.name | string | `nil` | | +# Prometheus + +[Prometheus](https://prometheus.io/), a [Cloud Native Computing Foundation](https://cncf.io/) project, is a systems and service monitoring system. It collects metrics from configured targets at given intervals, evaluates rule expressions, displays the results, and can trigger alerts if some condition is observed to be true. + +## TL;DR; + +```console +$ helm install stable/prometheus +``` + +## Introduction + +This chart bootstraps a [Prometheus](https://prometheus.io/) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes 1.3+ with Beta APIs enabled + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm install --name my-release stable/prometheus +``` + +The command deploys Prometheus on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Prometheus 2.x + +Prometheus version 2.x has made changes to alertmanager, storage and recording rules. Check out the migration guide [here](https://prometheus.io/docs/prometheus/2.0/migration/) + +Users of this chart will need to update their alerting rules to the new format before they can upgrade. + +## Upgrading from previous chart versions. + +Version 9.0 adds a new option to enable or disable the Prometheus Server. +This supports the use case of running a Prometheus server in one k8s cluster and scraping exporters in another cluster while using the same chart for each deployment. +To install the server `server.enabled` must be set to `true`. + +As of version 5.0, this chart uses Prometheus 2.x. This version of prometheus introduces a new data format and is not compatible with prometheus 1.x. It is recommended to install this as a new release, as updating existing releases will not work. See the [prometheus docs](https://prometheus.io/docs/prometheus/latest/migration/#storage) for instructions on retaining your old data. + +### Example migration + +Assuming you have an existing release of the prometheus chart, named `prometheus-old`. In order to update to prometheus 2.x while keeping your old data do the following: + +1. Update the `prometheus-old` release. Disable scraping on every component besides the prometheus server, similar to the configuration below: + + ``` + alertmanager: + enabled: false + alertmanagerFiles: + alertmanager.yml: "" + kubeStateMetrics: + enabled: false + nodeExporter: + enabled: false + pushgateway: + enabled: false + server: + extraArgs: + storage.local.retention: 720h + serverFiles: + alerts: "" + prometheus.yml: "" + rules: "" + ``` + +1. Deploy a new release of the chart with version 5.0+ using prometheus 2.x. In the values.yaml set the scrape config as usual, and also add the `prometheus-old` instance as a remote-read target. + + ``` + prometheus.yml: + ... + remote_read: + - url: http://prometheus-old/api/v1/read + ... + ``` + + Old data will be available when you query the new prometheus instance. + +## Scraping Pod Metrics via Annotations + +This chart uses a default configuration that causes prometheus +to scrape a variety of kubernetes resource types, provided they have the correct annotations. +In this section we describe how to configure pods to be scraped; +for information on how other resource types can be scraped you can +do a `helm template` to get the kubernetes resource definitions, +and then reference the prometheus configuration in the ConfigMap against the prometheus documentation +for [relabel_config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) +and [kubernetes_sd_config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config). + +In order to get prometheus to scrape pods, you must add annotations to the the pods as below: + +``` +metadata: + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: /metrics + prometheus.io/port: "8080" +spec: +... +``` + +You should adjust `prometheus.io/path` based on the URL that your pod serves metrics from. +`prometheus.io/port` should be set to the port that your pod serves metrics from. +Note that the values for `prometheus.io/scrape` and `prometheus.io/port` must be +enclosed in double quotes. + +## Configuration + +The following table lists the configurable parameters of the Prometheus chart and their default values. + +Parameter | Description | Default +--------- | ----------- | ------- +`alertmanager.enabled` | If true, create alertmanager | `true` +`alertmanager.name` | alertmanager container name | `alertmanager` +`alertmanager.image.repository` | alertmanager container image repository | `prom/alertmanager` +`alertmanager.image.tag` | alertmanager container image tag | `v0.20.0` +`alertmanager.image.pullPolicy` | alertmanager container image pull policy | `IfNotPresent` +`alertmanager.prefixURL` | The prefix slug at which the server can be accessed | `` +`alertmanager.baseURL` | The external url at which the server can be accessed | `"http://localhost:9093"` +`alertmanager.extraArgs` | Additional alertmanager container arguments | `{}` +`alertmanager.extraSecretMounts` | Additional alertmanager Secret mounts | `[]` +`alertmanager.configMapOverrideName` | Prometheus alertmanager ConfigMap override where full-name is `{{.Release.Name}}-{{.Values.alertmanager.configMapOverrideName}}` and setting this value will prevent the default alertmanager ConfigMap from being generated | `""` +`alertmanager.configFromSecret` | The name of a secret in the same kubernetes namespace which contains the Alertmanager config, setting this value will prevent the default alertmanager ConfigMap from being generated | `""` +`alertmanager.configFileName` | The configuration file name to be loaded to alertmanager. Must match the key within configuration loaded from ConfigMap/Secret. | `alertmanager.yml` +`alertmanager.ingress.enabled` | If true, alertmanager Ingress will be created | `false` +`alertmanager.ingress.annotations` | alertmanager Ingress annotations | `{}` +`alertmanager.ingress.extraLabels` | alertmanager Ingress additional labels | `{}` +`alertmanager.ingress.hosts` | alertmanager Ingress hostnames | `[]` +`alertmanager.ingress.extraPaths` | Ingress extra paths to prepend to every alertmanager host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions) | `[]` +`alertmanager.ingress.tls` | alertmanager Ingress TLS configuration (YAML) | `[]` +`alertmanager.nodeSelector` | node labels for alertmanager pod assignment | `{}` +`alertmanager.tolerations` | node taints to tolerate (requires Kubernetes >=1.6) | `[]` +`alertmanager.affinity` | pod affinity | `{}` +`alertmanager.podDisruptionBudget.enabled` | If true, create a PodDisruptionBudget | `false` +`alertmanager.podDisruptionBudget.maxUnavailable` | Maximum unavailable instances in PDB | `1` +`alertmanager.schedulerName` | alertmanager alternate scheduler name | `nil` +`alertmanager.persistentVolume.enabled` | If true, alertmanager will create a Persistent Volume Claim | `true` +`alertmanager.persistentVolume.accessModes` | alertmanager data Persistent Volume access modes | `[ReadWriteOnce]` +`alertmanager.persistentVolume.annotations` | Annotations for alertmanager Persistent Volume Claim | `{}` +`alertmanager.persistentVolume.existingClaim` | alertmanager data Persistent Volume existing claim name | `""` +`alertmanager.persistentVolume.mountPath` | alertmanager data Persistent Volume mount root path | `/data` +`alertmanager.persistentVolume.size` | alertmanager data Persistent Volume size | `2Gi` +`alertmanager.persistentVolume.storageClass` | alertmanager data Persistent Volume Storage Class | `unset` +`alertmanager.persistentVolume.volumeBindingMode` | alertmanager data Persistent Volume Binding Mode | `unset` +`alertmanager.persistentVolume.subPath` | Subdirectory of alertmanager data Persistent Volume to mount | `""` +`alertmanager.podAnnotations` | annotations to be added to alertmanager pods | `{}` +`alertmanager.podLabels` | labels to be added to Prometheus AlertManager pods | `{}` +`alertmanager.podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | +`alertmanager.replicaCount` | desired number of alertmanager pods | `1` +`alertmanager.statefulSet.enabled` | If true, use a statefulset instead of a deployment for pod management | `false` +`alertmanager.statefulSet.podManagementPolicy` | podManagementPolicy of alertmanager pods | `OrderedReady` +`alertmanager.statefulSet.headless.annotations` | annotations for alertmanager headless service | `{}` +`alertmanager.statefulSet.headless.labels` | labels for alertmanager headless service | `{}` +`alertmanager.statefulSet.headless.enableMeshPeer` | If true, enable the mesh peer endpoint for the headless service | `{}` +`alertmanager.statefulSet.headless.servicePort` | alertmanager headless service port | `80` +`alertmanager.priorityClassName` | alertmanager priorityClassName | `nil` +`alertmanager.resources` | alertmanager pod resource requests & limits | `{}` +`alertmanager.securityContext` | Custom [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for Alert Manager containers | `{}` +`alertmanager.service.annotations` | annotations for alertmanager service | `{}` +`alertmanager.service.clusterIP` | internal alertmanager cluster service IP | `""` +`alertmanager.service.externalIPs` | alertmanager service external IP addresses | `[]` +`alertmanager.service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` +`alertmanager.service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to load balancer (if supported) | `[]` +`alertmanager.service.servicePort` | alertmanager service port | `80` +`alertmanager.service.sessionAffinity` | Session Affinity for alertmanager service, can be `None` or `ClientIP` | `None` +`alertmanager.service.type` | type of alertmanager service to create | `ClusterIP` +`alertmanager.strategy` | Deployment strategy | `{ "type": "RollingUpdate" }` +`alertmanagerFiles.alertmanager.yml` | Prometheus alertmanager configuration | example configuration +`configmapReload.prometheus.enabled` | If false, the configmap-reload container for Prometheus will not be deployed | `true` +`configmapReload.prometheus.name` | configmap-reload container name | `configmap-reload` +`configmapReload.prometheus.image.repository` | configmap-reload container image repository | `jimmidyson/configmap-reload` +`configmapReload.prometheus.image.tag` | configmap-reload container image tag | `v0.3.0` +`configmapReload.prometheus.image.pullPolicy` | configmap-reload container image pull policy | `IfNotPresent` +`configmapReload.prometheus.extraArgs` | Additional configmap-reload container arguments | `{}` +`configmapReload.prometheus.extraVolumeDirs` | Additional configmap-reload volume directories | `{}` +`configmapReload.prometheus.extraConfigmapMounts` | Additional configmap-reload configMap mounts | `[]` +`configmapReload.prometheus.resources` | configmap-reload pod resource requests & limits | `{}` +`configmapReload.alertmanager.enabled` | If false, the configmap-reload container for AlertManager will not be deployed | `true` +`configmapReload.alertmanager.name` | configmap-reload container name | `configmap-reload` +`configmapReload.alertmanager.image.repository` | configmap-reload container image repository | `jimmidyson/configmap-reload` +`configmapReload.alertmanager.image.tag` | configmap-reload container image tag | `v0.3.0` +`configmapReload.alertmanager.image.pullPolicy` | configmap-reload container image pull policy | `IfNotPresent` +`configmapReload.alertmanager.extraArgs` | Additional configmap-reload container arguments | `{}` +`configmapReload.alertmanager.extraVolumeDirs` | Additional configmap-reload volume directories | `{}` +`configmapReload.alertmanager.extraConfigmapMounts` | Additional configmap-reload configMap mounts | `[]` +`configmapReload.alertmanager.resources` | configmap-reload pod resource requests & limits | `{}` +`initChownData.enabled` | If false, don't reset data ownership at startup | true +`initChownData.name` | init-chown-data container name | `init-chown-data` +`initChownData.image.repository` | init-chown-data container image repository | `busybox` +`initChownData.image.tag` | init-chown-data container image tag | `latest` +`initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` +`initChownData.resources` | init-chown-data pod resource requests & limits | `{}` +`kubeStateMetrics.enabled` | If true, create kube-state-metrics sub-chart, see the [kube-state-metrics chart for configuration options](https://github.com/helm/charts/tree/master/stable/kube-state-metrics) | `true` +`nodeExporter.enabled` | If true, create node-exporter | `true` +`nodeExporter.name` | node-exporter container name | `node-exporter` +`nodeExporter.image.repository` | node-exporter container image repository| `prom/node-exporter` +`nodeExporter.image.tag` | node-exporter container image tag | `v0.18.1` +`nodeExporter.image.pullPolicy` | node-exporter container image pull policy | `IfNotPresent` +`nodeExporter.extraArgs` | Additional node-exporter container arguments | `{}` +`nodeExporter.extraHostPathMounts` | Additional node-exporter hostPath mounts | `[]` +`nodeExporter.extraConfigmapMounts` | Additional node-exporter configMap mounts | `[]` +`nodeExporter.hostNetwork` | If true, node-exporter pods share the host network namespace | `true` +`nodeExporter.hostPID` | If true, node-exporter pods share the host PID namespace | `true` +`nodeExporter.nodeSelector` | node labels for node-exporter pod assignment | `{}` +`nodeExporter.podAnnotations` | annotations to be added to node-exporter pods | `{}` +`nodeExporter.pod.labels` | labels to be added to node-exporter pods | `{}` +`nodeExporter.podDisruptionBudget.enabled` | If true, create a PodDisruptionBudget | `false` +`nodeExporter.podDisruptionBudget.maxUnavailable` | Maximum unavailable instances in PDB | `1` +`nodeExporter.podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | +`nodeExporter.podSecurityPolicy.enabled` | Specify if a Pod Security Policy for node-exporter must be created | `false` +`nodeExporter.tolerations` | node taints to tolerate (requires Kubernetes >=1.6) | `[]` +`nodeExporter.priorityClassName` | node-exporter priorityClassName | `nil` +`nodeExporter.resources` | node-exporter resource requests and limits (YAML) | `{}` +`nodeExporter.securityContext` | securityContext for containers in pod | `{}` +`nodeExporter.service.annotations` | annotations for node-exporter service | `{prometheus.io/scrape: "true"}` +`nodeExporter.service.clusterIP` | internal node-exporter cluster service IP | `None` +`nodeExporter.service.externalIPs` | node-exporter service external IP addresses | `[]` +`nodeExporter.service.hostPort` | node-exporter service host port | `9100` +`nodeExporter.service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` +`nodeExporter.service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to load balancer (if supported) | `[]` +`nodeExporter.service.servicePort` | node-exporter service port | `9100` +`nodeExporter.service.type` | type of node-exporter service to create | `ClusterIP` +`podSecurityPolicy.enabled` | If true, create & use pod security policies resources | `false` +`pushgateway.enabled` | If true, create pushgateway | `true` +`pushgateway.name` | pushgateway container name | `pushgateway` +`pushgateway.image.repository` | pushgateway container image repository | `prom/pushgateway` +`pushgateway.image.tag` | pushgateway container image tag | `v1.0.1` +`pushgateway.image.pullPolicy` | pushgateway container image pull policy | `IfNotPresent` +`pushgateway.extraArgs` | Additional pushgateway container arguments | `{}` +`pushgateway.ingress.enabled` | If true, pushgateway Ingress will be created | `false` +`pushgateway.ingress.annotations` | pushgateway Ingress annotations | `{}` +`pushgateway.ingress.hosts` | pushgateway Ingress hostnames | `[]` +`pushgateway.ingress.extraPaths` | Ingress extra paths to prepend to every pushgateway host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions) | `[]` +`pushgateway.ingress.tls` | pushgateway Ingress TLS configuration (YAML) | `[]` +`pushgateway.nodeSelector` | node labels for pushgateway pod assignment | `{}` +`pushgateway.podAnnotations` | annotations to be added to pushgateway pods | `{}` +`pushgateway.podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | +`pushgateway.tolerations` | node taints to tolerate (requires Kubernetes >=1.6) | `[]` +`pushgateway.replicaCount` | desired number of pushgateway pods | `1` +`pushgateway.podDisruptionBudget.enabled` | If true, create a PodDisruptionBudget | `false` +`pushgateway.podDisruptionBudget.maxUnavailable` | Maximum unavailable instances in PDB | `1` +`pushgateway.schedulerName` | pushgateway alternate scheduler name | `nil` +`pushgateway.persistentVolume.enabled` | If true, Prometheus pushgateway will create a Persistent Volume Claim | `false` +`pushgateway.persistentVolume.accessModes` | Prometheus pushgateway data Persistent Volume access modes | `[ReadWriteOnce]` +`pushgateway.persistentVolume.annotations` | Prometheus pushgateway data Persistent Volume annotations | `{}` +`pushgateway.persistentVolume.existingClaim` | Prometheus pushgateway data Persistent Volume existing claim name | `""` +`pushgateway.persistentVolume.mountPath` | Prometheus pushgateway data Persistent Volume mount root path | `/data` +`pushgateway.persistentVolume.size` | Prometheus pushgateway data Persistent Volume size | `2Gi` +`pushgateway.persistentVolume.storageClass` | Prometheus pushgateway data Persistent Volume Storage Class | `unset` +`pushgateway.persistentVolume.volumeBindingMode` | Prometheus pushgateway data Persistent Volume Binding Mode | `unset` +`pushgateway.persistentVolume.subPath` | Subdirectory of Prometheus server data Persistent Volume to mount | `""` +`pushgateway.priorityClassName` | pushgateway priorityClassName | `nil` +`pushgateway.resources` | pushgateway pod resource requests & limits | `{}` +`pushgateway.service.annotations` | annotations for pushgateway service | `{}` +`pushgateway.service.clusterIP` | internal pushgateway cluster service IP | `""` +`pushgateway.service.externalIPs` | pushgateway service external IP addresses | `[]` +`pushgateway.service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` +`pushgateway.service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to load balancer (if supported) | `[]` +`pushgateway.service.servicePort` | pushgateway service port | `9091` +`pushgateway.service.type` | type of pushgateway service to create | `ClusterIP` +`pushgateway.strategy` | Deployment strategy | `{ "type": "RollingUpdate" }` +`rbac.create` | If true, create & use RBAC resources | `true` +`server.enabled` | If false, Prometheus server will not be created | `true` +`server.name` | Prometheus server container name | `server` +`server.image.repository` | Prometheus server container image repository | `prom/prometheus` +`server.image.tag` | Prometheus server container image tag | `v2.16.0` +`server.image.pullPolicy` | Prometheus server container image pull policy | `IfNotPresent` +`server.configPath` | Path to a prometheus server config file on the container FS | `/etc/config/prometheus.yml` +`server.global.scrape_interval` | How frequently to scrape targets by default | `1m` +`server.global.scrape_timeout` | How long until a scrape request times out | `10s` +`server.global.evaluation_interval` | How frequently to evaluate rules | `1m` +`server.remoteWrite` | The remote write feature of Prometheus allow transparently sending samples. | `{}` +`server.remoteRead` | The remote read feature of Prometheus allow transparently receiving samples. | `{}` +`server.extraArgs` | Additional Prometheus server container arguments | `{}` +`server.extraFlags` | Additional Prometheus server container flags | `["web.enable-lifecycle"]` +`server.extraInitContainers` | Init containers to launch alongside the server | `[]` +`server.prefixURL` | The prefix slug at which the server can be accessed | `` +`server.baseURL` | The external url at which the server can be accessed | `` +`server.env` | Prometheus server environment variables | `[]` +`server.extraHostPathMounts` | Additional Prometheus server hostPath mounts | `[]` +`server.extraConfigmapMounts` | Additional Prometheus server configMap mounts | `[]` +`server.extraSecretMounts` | Additional Prometheus server Secret mounts | `[]` +`server.extraVolumeMounts` | Additional Prometheus server Volume mounts | `[]` +`server.extraVolumes` | Additional Prometheus server Volumes | `[]` +`server.configMapOverrideName` | Prometheus server ConfigMap override where full-name is `{{.Release.Name}}-{{.Values.server.configMapOverrideName}}` and setting this value will prevent the default server ConfigMap from being generated | `""` +`server.ingress.enabled` | If true, Prometheus server Ingress will be created | `false` +`server.ingress.annotations` | Prometheus server Ingress annotations | `[]` +`server.ingress.extraLabels` | Prometheus server Ingress additional labels | `{}` +`server.ingress.hosts` | Prometheus server Ingress hostnames | `[]` +`server.ingress.extraPaths` | Ingress extra paths to prepend to every Prometheus server host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions) | `[]` +`server.ingress.tls` | Prometheus server Ingress TLS configuration (YAML) | `[]` +`server.nodeSelector` | node labels for Prometheus server pod assignment | `{}` +`server.tolerations` | node taints to tolerate (requires Kubernetes >=1.6) | `[]` +`server.affinity` | pod affinity | `{}` +`server.podDisruptionBudget.enabled` | If true, create a PodDisruptionBudget | `false` +`server.podDisruptionBudget.maxUnavailable` | Maximum unavailable instances in PDB | `1` +`server.priorityClassName` | Prometheus server priorityClassName | `nil` +`server.schedulerName` | Prometheus server alternate scheduler name | `nil` +`server.persistentVolume.enabled` | If true, Prometheus server will create a Persistent Volume Claim | `true` +`server.persistentVolume.accessModes` | Prometheus server data Persistent Volume access modes | `[ReadWriteOnce]` +`server.persistentVolume.annotations` | Prometheus server data Persistent Volume annotations | `{}` +`server.persistentVolume.existingClaim` | Prometheus server data Persistent Volume existing claim name | `""` +`server.persistentVolume.mountPath` | Prometheus server data Persistent Volume mount root path | `/data` +`server.persistentVolume.size` | Prometheus server data Persistent Volume size | `8Gi` +`server.persistentVolume.storageClass` | Prometheus server data Persistent Volume Storage Class | `unset` +`server.persistentVolume.volumeBindingMode` | Prometheus server data Persistent Volume Binding Mode | `unset` +`server.persistentVolume.subPath` | Subdirectory of Prometheus server data Persistent Volume to mount | `""` +`server.emptyDir.sizeLimit` | emptyDir sizeLimit if a Persistent Volume is not used | `""` +`server.podAnnotations` | annotations to be added to Prometheus server pods | `{}` +`server.podLabels` | labels to be added to Prometheus server pods | `{}` +`server.alertmanagers` | Prometheus AlertManager configuration for the Prometheus server | `{}` +`server.deploymentAnnotations` | annotations to be added to Prometheus server deployment | `{}` +`server.podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | +`server.replicaCount` | desired number of Prometheus server pods | `1` +`server.statefulSet.enabled` | If true, use a statefulset instead of a deployment for pod management | `false` +`server.statefulSet.annotations` | annotations to be added to Prometheus server stateful set | `{}` +`server.statefulSet.labels` | labels to be added to Prometheus server stateful set | `{}` +`server.statefulSet.podManagementPolicy` | podManagementPolicy of server pods | `OrderedReady` +`server.statefulSet.headless.annotations` | annotations for Prometheus server headless service | `{}` +`server.statefulSet.headless.labels` | labels for Prometheus server headless service | `{}` +`server.statefulSet.headless.servicePort` | Prometheus server headless service port | `80` +`server.resources` | Prometheus server resource requests and limits | `{}` +`server.verticalAutoscaler.enabled` | If true a VPA object will be created for the controller (either StatefulSet or Deployemnt, based on above configs) | `false` +`server.securityContext` | Custom [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for server containers | `{}` +`server.service.annotations` | annotations for Prometheus server service | `{}` +`server.service.clusterIP` | internal Prometheus server cluster service IP | `""` +`server.service.externalIPs` | Prometheus server service external IP addresses | `[]` +`server.service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` +`server.service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to load balancer (if supported) | `[]` +`server.service.nodePort` | Port to be used as the service NodePort (ignored if `server.service.type` is not `NodePort`) | `0` +`server.service.servicePort` | Prometheus server service port | `80` +`server.service.sessionAffinity` | Session Affinity for server service, can be `None` or `ClientIP` | `None` +`server.service.type` | type of Prometheus server service to create | `ClusterIP` +`server.service.gRPC.enabled` | If true, open a second port on the service for gRPC | `false` +`server.service.gRPC.servicePort` | Prometheus service gRPC port, (ignored if `server.service.gRPC.enabled` is not `true`) | `10901` +`server.service.gRPC.nodePort` | Port to be used as gRPC nodePort in the prometheus service | `0` +`server.service.statefulsetReplica.enabled` | If true, send the traffic from the service to only one replica of the replicaset | `false` +`server.service.statefulsetReplica.replica` | Which replica to send the traffice to | `0` +`server.sidecarContainers` | array of snippets with your sidecar containers for prometheus server | `""` +`server.strategy` | Deployment strategy | `{ "type": "RollingUpdate" }` +`serviceAccounts.alertmanager.create` | If true, create the alertmanager service account | `true` +`serviceAccounts.alertmanager.name` | name of the alertmanager service account to use or create | `{{ prometheus.alertmanager.fullname }}` +`serviceAccounts.kubeStateMetrics.create` | If true, create the kubeStateMetrics service account | `true` +`serviceAccounts.kubeStateMetrics.name` | name of the kubeStateMetrics service account to use or create | `{{ prometheus.kubeStateMetrics.fullname }}` +`serviceAccounts.nodeExporter.create` | If true, create the nodeExporter service account | `true` +`serviceAccounts.nodeExporter.name` | name of the nodeExporter service account to use or create | `{{ prometheus.nodeExporter.fullname }}` +`serviceAccounts.pushgateway.create` | If true, create the pushgateway service account | `true` +`serviceAccounts.pushgateway.name` | name of the pushgateway service account to use or create | `{{ prometheus.pushgateway.fullname }}` +`serviceAccounts.server.create` | If true, create the server service account | `true` +`serviceAccounts.server.name` | name of the server service account to use or create | `{{ prometheus.server.fullname }}` +`server.terminationGracePeriodSeconds` | Prometheus server Pod termination grace period | `300` +`server.retention` | (optional) Prometheus data retention | `"15d"` +`serverFiles.alerts` | (Deprecated) Prometheus server alerts configuration | `{}` +`serverFiles.rules` | (Deprecated) Prometheus server rules configuration | `{}` +`serverFiles.alerting_rules.yml` | Prometheus server alerts configuration | `{}` +`serverFiles.recording_rules.yml` | Prometheus server rules configuration | `{}` +`serverFiles.prometheus.yml` | Prometheus server scrape configuration | example configuration +`extraScrapeConfigs` | Prometheus server additional scrape configuration | "" +`alertRelabelConfigs` | Prometheus server [alert relabeling configs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs) for H/A prometheus | "" +`networkPolicy.enabled` | Enable NetworkPolicy | `false` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install stable/prometheus --name my-release \ + --set server.terminationGracePeriodSeconds=360 +``` + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +$ helm install stable/prometheus --name my-release -f values.yaml +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +Note that you have multiple yaml files. This is particularly useful when you have alerts belonging to multiple services in the cluster. For example, + +```yaml +# values.yaml +# ... + +# service1-alert.yaml +serverFiles: + alerts: + service1: + - alert: anAlert + # ... + +# service2-alert.yaml +serverFiles: + alerts: + service2: + - alert: anAlert + # ... +``` + +```console +$ helm install stable/prometheus --name my-release -f values.yaml -f service1-alert.yaml -f service2-alert.yaml +``` + +### RBAC Configuration +Roles and RoleBindings resources will be created automatically for `server` and `kubeStateMetrics` services. + +To manually setup RBAC you need to set the parameter `rbac.create=false` and specify the service account to be used for each service by setting the parameters: `serviceAccounts.{{ component }}.create` to `false` and `serviceAccounts.{{ component }}.name` to the name of a pre-existing service account. + +> **Tip**: You can refer to the default `*-clusterrole.yaml` and `*-clusterrolebinding.yaml` files in [templates](templates/) to customize your own. + +### ConfigMap Files +AlertManager is configured through [alertmanager.yml](https://prometheus.io/docs/alerting/configuration/). This file (and any others listed in `alertmanagerFiles`) will be mounted into the `alertmanager` pod. + +Prometheus is configured through [prometheus.yml](https://prometheus.io/docs/operating/configuration/). This file (and any others listed in `serverFiles`) will be mounted into the `server` pod. + +### Ingress TLS +If your cluster allows automatic creation/retrieval of TLS certificates (e.g. [kube-lego](https://github.com/jetstack/kube-lego)), please refer to the documentation for that mechanism. + +To manually configure TLS, first create/retrieve a key & certificate pair for the address(es) you wish to protect. Then create a TLS secret in the namespace: + +```console +kubectl create secret tls prometheus-server-tls --cert=path/to/tls.cert --key=path/to/tls.key +``` + +Include the secret's name, along with the desired hostnames, in the alertmanager/server Ingress TLS section of your custom `values.yaml` file: + +```yaml +server: + ingress: + ## If true, Prometheus server Ingress will be created + ## + enabled: true + + ## Prometheus server Ingress hostnames + ## Must be provided if Ingress is enabled + ## + hosts: + - prometheus.domain.com + + ## Prometheus server Ingress TLS configuration + ## Secrets must be manually created in the namespace + ## + tls: + - secretName: prometheus-server-tls + hosts: + - prometheus.domain.com +``` + +### NetworkPolicy + +Enabling Network Policy for Prometheus will secure connections to Alert Manager +and Kube State Metrics by only accepting connections from Prometheus Server. +All inbound connections to Prometheus Server are still allowed. + +To enable network policy for Prometheus, install a networking plugin that +implements the Kubernetes NetworkPolicy spec, and set `networkPolicy.enabled` to true. + +If NetworkPolicy is enabled for Prometheus' scrape targets, you may also need +to manually create a networkpolicy which allows it. diff --git a/infra/charts/feast/charts/redis/README.md b/infra/charts/feast/charts/redis/README.md index 8d56e897fd3..72eb8364227 100644 --- a/infra/charts/feast/charts/redis/README.md +++ b/infra/charts/feast/charts/redis/README.md @@ -1,169 +1,497 @@ -redis -===== -Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. - -Current chart version is `10.5.6` - -Source code can be found [here](http://redis.io/) - - - -## Chart Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| cluster.enabled | bool | `false` | | -| cluster.slaveCount | int | `1` | | -| clusterDomain | string | `"cluster.local"` | | -| configmap | string | `"# Enable AOF https://redis.io/topics/persistence#append-only-file\nappendonly yes\n# Disable RDB persistence, AOF persistence already enabled.\nsave \"\""` | | -| global.redis | object | `{}` | | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.registry | string | `"docker.io"` | | -| image.repository | string | `"bitnami/redis"` | | -| image.tag | string | `"5.0.7-debian-10-r32"` | | -| master.affinity | object | `{}` | | -| master.command | string | `"/run.sh"` | | -| master.configmap | string | `nil` | | -| master.disableCommands[0] | string | `"FLUSHDB"` | | -| master.disableCommands[1] | string | `"FLUSHALL"` | | -| master.extraFlags | list | `[]` | | -| master.livenessProbe.enabled | bool | `true` | | -| master.livenessProbe.failureThreshold | int | `5` | | -| master.livenessProbe.initialDelaySeconds | int | `5` | | -| master.livenessProbe.periodSeconds | int | `5` | | -| master.livenessProbe.successThreshold | int | `1` | | -| master.livenessProbe.timeoutSeconds | int | `5` | | -| master.persistence.accessModes[0] | string | `"ReadWriteOnce"` | | -| master.persistence.enabled | bool | `true` | | -| master.persistence.matchExpressions | object | `{}` | | -| master.persistence.matchLabels | object | `{}` | | -| master.persistence.path | string | `"/data"` | | -| master.persistence.size | string | `"8Gi"` | | -| master.persistence.subPath | string | `""` | | -| master.podAnnotations | object | `{}` | | -| master.podLabels | object | `{}` | | -| master.readinessProbe.enabled | bool | `true` | | -| master.readinessProbe.failureThreshold | int | `5` | | -| master.readinessProbe.initialDelaySeconds | int | `5` | | -| master.readinessProbe.periodSeconds | int | `5` | | -| master.readinessProbe.successThreshold | int | `1` | | -| master.readinessProbe.timeoutSeconds | int | `1` | | -| master.service.annotations | object | `{}` | | -| master.service.labels | object | `{}` | | -| master.service.loadBalancerIP | string | `nil` | | -| master.service.port | int | `6379` | | -| master.service.type | string | `"ClusterIP"` | | -| master.statefulset.updateStrategy | string | `"RollingUpdate"` | | -| metrics.enabled | bool | `false` | | -| metrics.image.pullPolicy | string | `"IfNotPresent"` | | -| metrics.image.registry | string | `"docker.io"` | | -| metrics.image.repository | string | `"bitnami/redis-exporter"` | | -| metrics.image.tag | string | `"1.4.0-debian-10-r3"` | | -| metrics.podAnnotations."prometheus.io/port" | string | `"9121"` | | -| metrics.podAnnotations."prometheus.io/scrape" | string | `"true"` | | -| metrics.prometheusRule.additionalLabels | object | `{}` | | -| metrics.prometheusRule.enabled | bool | `false` | | -| metrics.prometheusRule.namespace | string | `""` | | -| metrics.prometheusRule.rules | list | `[]` | | -| metrics.service.annotations | object | `{}` | | -| metrics.service.labels | object | `{}` | | -| metrics.service.type | string | `"ClusterIP"` | | -| metrics.serviceMonitor.enabled | bool | `false` | | -| metrics.serviceMonitor.selector.prometheus | string | `"kube-prometheus"` | | -| networkPolicy.enabled | bool | `false` | | -| networkPolicy.ingressNSMatchLabels | object | `{}` | | -| networkPolicy.ingressNSPodMatchLabels | object | `{}` | | -| password | string | `""` | | -| persistence | object | `{}` | | -| podSecurityPolicy.create | bool | `false` | | -| rbac.create | bool | `false` | | -| rbac.role.rules | list | `[]` | | -| redisPort | int | `6379` | | -| securityContext.enabled | bool | `true` | | -| securityContext.fsGroup | int | `1001` | | -| securityContext.runAsUser | int | `1001` | | -| sentinel.configmap | string | `nil` | | -| sentinel.downAfterMilliseconds | int | `60000` | | -| sentinel.enabled | bool | `false` | | -| sentinel.failoverTimeout | int | `18000` | | -| sentinel.image.pullPolicy | string | `"IfNotPresent"` | | -| sentinel.image.registry | string | `"docker.io"` | | -| sentinel.image.repository | string | `"bitnami/redis-sentinel"` | | -| sentinel.image.tag | string | `"5.0.7-debian-10-r27"` | | -| sentinel.initialCheckTimeout | int | `5` | | -| sentinel.livenessProbe.enabled | bool | `true` | | -| sentinel.livenessProbe.failureThreshold | int | `5` | | -| sentinel.livenessProbe.initialDelaySeconds | int | `5` | | -| sentinel.livenessProbe.periodSeconds | int | `5` | | -| sentinel.livenessProbe.successThreshold | int | `1` | | -| sentinel.livenessProbe.timeoutSeconds | int | `5` | | -| sentinel.masterSet | string | `"mymaster"` | | -| sentinel.parallelSyncs | int | `1` | | -| sentinel.port | int | `26379` | | -| sentinel.quorum | int | `2` | | -| sentinel.readinessProbe.enabled | bool | `true` | | -| sentinel.readinessProbe.failureThreshold | int | `5` | | -| sentinel.readinessProbe.initialDelaySeconds | int | `5` | | -| sentinel.readinessProbe.periodSeconds | int | `5` | | -| sentinel.readinessProbe.successThreshold | int | `1` | | -| sentinel.readinessProbe.timeoutSeconds | int | `1` | | -| sentinel.service.annotations | object | `{}` | | -| sentinel.service.labels | object | `{}` | | -| sentinel.service.loadBalancerIP | string | `nil` | | -| sentinel.service.redisPort | int | `6379` | | -| sentinel.service.sentinelPort | int | `26379` | | -| sentinel.service.type | string | `"ClusterIP"` | | -| sentinel.staticID | bool | `false` | | -| sentinel.usePassword | bool | `true` | | -| serviceAccount.create | bool | `false` | | -| serviceAccount.name | string | `nil` | | -| slave.affinity | object | `{}` | | -| slave.command | string | `"/run.sh"` | | -| slave.configmap | string | `nil` | | -| slave.disableCommands[0] | string | `"FLUSHDB"` | | -| slave.disableCommands[1] | string | `"FLUSHALL"` | | -| slave.extraFlags | list | `[]` | | -| slave.livenessProbe.enabled | bool | `true` | | -| slave.livenessProbe.failureThreshold | int | `5` | | -| slave.livenessProbe.initialDelaySeconds | int | `30` | | -| slave.livenessProbe.periodSeconds | int | `10` | | -| slave.livenessProbe.successThreshold | int | `1` | | -| slave.livenessProbe.timeoutSeconds | int | `5` | | -| slave.persistence.accessModes[0] | string | `"ReadWriteOnce"` | | -| slave.persistence.enabled | bool | `true` | | -| slave.persistence.matchExpressions | object | `{}` | | -| slave.persistence.matchLabels | object | `{}` | | -| slave.persistence.path | string | `"/data"` | | -| slave.persistence.size | string | `"8Gi"` | | -| slave.persistence.subPath | string | `""` | | -| slave.podAnnotations | object | `{}` | | -| slave.podLabels | object | `{}` | | -| slave.port | int | `6379` | | -| slave.readinessProbe.enabled | bool | `true` | | -| slave.readinessProbe.failureThreshold | int | `5` | | -| slave.readinessProbe.initialDelaySeconds | int | `5` | | -| slave.readinessProbe.periodSeconds | int | `10` | | -| slave.readinessProbe.successThreshold | int | `1` | | -| slave.readinessProbe.timeoutSeconds | int | `10` | | -| slave.service.annotations | object | `{}` | | -| slave.service.labels | object | `{}` | | -| slave.service.loadBalancerIP | string | `nil` | | -| slave.service.port | int | `6379` | | -| slave.service.type | string | `"ClusterIP"` | | -| slave.statefulset.updateStrategy | string | `"RollingUpdate"` | | -| sysctlImage.command | list | `[]` | | -| sysctlImage.enabled | bool | `false` | | -| sysctlImage.mountHostSys | bool | `false` | | -| sysctlImage.pullPolicy | string | `"Always"` | | -| sysctlImage.registry | string | `"docker.io"` | | -| sysctlImage.repository | string | `"bitnami/minideb"` | | -| sysctlImage.resources | object | `{}` | | -| sysctlImage.tag | string | `"buster"` | | -| usePassword | bool | `false` | | -| usePasswordFile | bool | `false` | | -| volumePermissions.enabled | bool | `false` | | -| volumePermissions.image.pullPolicy | string | `"Always"` | | -| volumePermissions.image.registry | string | `"docker.io"` | | -| volumePermissions.image.repository | string | `"bitnami/minideb"` | | -| volumePermissions.image.tag | string | `"buster"` | | -| volumePermissions.resources | object | `{}` | | + +# Redis + +[Redis](http://redis.io/) is an advanced key-value cache and store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs. + +## TL;DR; + +```bash +# Testing configuration +$ helm install my-release stable/redis +``` + +```bash +# Production configuration +$ helm install my-release stable/redis --values values-production.yaml +``` + +## Introduction + +This chart bootstraps a [Redis](https://github.com/bitnami/bitnami-docker-redis) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.com/) for deployment and management of Helm Charts in clusters. This chart has been tested to work with NGINX Ingress, cert-manager, fluentd and Prometheus on top of the [BKPR](https://kubeprod.io/). + +## Prerequisites + +- Kubernetes 1.12+ +- Helm 2.11+ or Helm 3.0-beta3+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```bash +$ helm install my-release stable/redis +``` + +The command deploys Redis on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```bash +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Parameters + +The following table lists the configurable parameters of the Redis chart and their default values. + +| Parameter | Description | Default | +| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | +| `global.imageRegistry` | Global Docker image registry | `nil` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) | +| `global.storageClass` | Global storage class for dynamic provisioning | `nil` | +| `global.redis.password` | Redis password (overrides `password`) | `nil` | +| `image.registry` | Redis Image registry | `docker.io` | +| `image.repository` | Redis Image name | `bitnami/redis` | +| `image.tag` | Redis Image tag | `{TAG_NAME}` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Specify docker-registry secret names as an array | `nil` | +| `nameOverride` | String to partially override redis.fullname template with a string (will prepend the release name) | `nil` | +| `fullnameOverride` | String to fully override redis.fullname template with a string | `nil` | +| `cluster.enabled` | Use master-slave topology | `true` | +| `cluster.slaveCount` | Number of slaves | `1` | +| `existingSecret` | Name of existing secret object (for password authentication) | `nil` | +| `existingSecretPasswordKey` | Name of key containing password to be retrieved from the existing secret | `nil` | +| `usePassword` | Use password | `true` | +| `usePasswordFile` | Mount passwords as files instead of environment variables | `false` | +| `password` | Redis password (ignored if existingSecret set) | Randomly generated | +| `configmap` | Additional common Redis node configuration (this value is evaluated as a template) | See values.yaml | +| `clusterDomain` | Kubernetes DNS Domain name to use | `cluster.local` | +| `networkPolicy.enabled` | Enable NetworkPolicy | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.ingressNSMatchLabels` | Allow connections from other namespaces | `{}` | +| `networkPolicy.ingressNSPodMatchLabels` | For other namespaces match by pod labels and namespace labels | `{}` | +| `securityContext.enabled` | Enable security context (both redis master and slave pods) | `true` | +| `securityContext.fsGroup` | Group ID for the container (both redis master and slave pods) | `1001` | +| `securityContext.runAsUser` | User ID for the container (both redis master and slave pods) | `1001` | +| `securityContext.sysctls` | Set namespaced sysctls for the container (both redis master and slave pods) | `nil` | +| `serviceAccount.create` | Specifies whether a ServiceAccount should be created | `false` | +| `serviceAccount.name` | The name of the ServiceAccount to create | Generated using the fullname template | +| `rbac.create` | Specifies whether RBAC resources should be created | `false` | +| `rbac.role.rules` | Rules to create | `[]` | +| `metrics.enabled` | Start a side-car prometheus exporter | `false` | +| `metrics.image.registry` | Redis exporter image registry | `docker.io` | +| `metrics.image.repository` | Redis exporter image name | `bitnami/redis-exporter` | +| `metrics.image.tag` | Redis exporter image tag | `{TAG_NAME}` | +| `metrics.image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `nil` | +| `metrics.extraArgs` | Extra arguments for the binary; possible values [here](https://github.com/oliver006/redis_exporter#flags) | {} | +| `metrics.podLabels` | Additional labels for Metrics exporter pod | {} | +| `metrics.podAnnotations` | Additional annotations for Metrics exporter pod | {} | +| `metrics.resources` | Exporter resource requests/limit | Memory: `256Mi`, CPU: `100m` | +| `metrics.serviceMonitor.enabled` | if `true`, creates a Prometheus Operator ServiceMonitor (also requires `metrics.enabled` to be `true`) | `false` | +| `metrics.serviceMonitor.namespace` | Optional namespace which Prometheus is running in | `nil` | +| `metrics.serviceMonitor.interval` | How frequently to scrape metrics (use by default, falling back to Prometheus' default) | `nil` | +| `metrics.serviceMonitor.selector` | Default to kube-prometheus install (CoreOS recommended), but should be set according to Prometheus install | `{ prometheus: kube-prometheus }` | +| `metrics.service.type` | Kubernetes Service type (redis metrics) | `ClusterIP` | +| `metrics.service.annotations` | Annotations for the services to monitor (redis master and redis slave service) | {} | +| `metrics.service.labels` | Additional labels for the metrics service | {} | +| `metrics.service.loadBalancerIP` | loadBalancerIP if redis metrics service type is `LoadBalancer` | `nil` | +| `metrics.priorityClassName` | Metrics exporter pod priorityClassName | {} | +| `metrics.prometheusRule.enabled` | Set this to true to create prometheusRules for Prometheus operator | `false` | +| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so prometheusRules will be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.namespace` | namespace where prometheusRules resource should be created | Same namespace as redis | +| `metrics.prometheusRule.rules` | [rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) to be created, check values for an example. | `[]` | +| `persistence.existingClaim` | Provide an existing PersistentVolumeClaim | `nil` | +| `master.persistence.enabled` | Use a PVC to persist data (master node) | `true` | +| `master.persistence.path` | Path to mount the volume at, to use other images | `/data` | +| `master.persistence.subPath` | Subdirectory of the volume to mount at | `""` | +| `master.persistence.storageClass` | Storage class of backing PVC | `generic` | +| `master.persistence.accessModes` | Persistent Volume Access Modes | `[ReadWriteOnce]` | +| `master.persistence.size` | Size of data volume | `8Gi` | +| `master.persistence.matchLabels` | matchLabels persistent volume selector | `{}` | +| `master.persistence.matchExpressions` | matchExpressions persistent volume selector | `{}` | +| `master.statefulset.updateStrategy` | Update strategy for StatefulSet | onDelete | +| `master.statefulset.rollingUpdatePartition` | Partition update strategy | `nil` | +| `master.podLabels` | Additional labels for Redis master pod | {} | +| `master.podAnnotations` | Additional annotations for Redis master pod | {} | +| `redisPort` | Redis port (in both master and slaves) | `6379` | +| `master.command` | Redis master entrypoint string. The command `redis-server` is executed if this is not provided. | `/run.sh` | +| `master.configmap` | Additional Redis configuration for the master nodes (this value is evaluated as a template) | `nil` | +| `master.disableCommands` | Array of Redis commands to disable (master) | `["FLUSHDB", "FLUSHALL"]` | +| `master.extraFlags` | Redis master additional command line flags | [] | +| `master.nodeSelector` | Redis master Node labels for pod assignment | {"beta.kubernetes.io/arch": "amd64"} | +| `master.tolerations` | Toleration labels for Redis master pod assignment | [] | +| `master.affinity` | Affinity settings for Redis master pod assignment | {} | +| `master.schedulerName` | Name of an alternate scheduler | `nil` | +| `master.service.type` | Kubernetes Service type (redis master) | `ClusterIP` | +| `master.service.port` | Kubernetes Service port (redis master) | `6379` | +| `master.service.nodePort` | Kubernetes Service nodePort (redis master) | `nil` | +| `master.service.annotations` | annotations for redis master service | {} | +| `master.service.labels` | Additional labels for redis master service | {} | +| `master.service.loadBalancerIP` | loadBalancerIP if redis master service type is `LoadBalancer` | `nil` | +| `master.service.loadBalancerSourceRanges` | loadBalancerSourceRanges if redis master service type is `LoadBalancer` | `nil` | +| `master.resources` | Redis master CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | +| `master.livenessProbe.enabled` | Turn on and off liveness probe (redis master pod) | `true` | +| `master.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (redis master pod) | `30` | +| `master.livenessProbe.periodSeconds` | How often to perform the probe (redis master pod) | `30` | +| `master.livenessProbe.timeoutSeconds` | When the probe times out (redis master pod) | `5` | +| `master.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis master pod) | `1` | +| `master.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | +| `master.readinessProbe.enabled` | Turn on and off readiness probe (redis master pod) | `true` | +| `master.readinessProbe.initialDelaySeconds` | Delay before readiness probe is initiated (redis master pod) | `5` | +| `master.readinessProbe.periodSeconds` | How often to perform the probe (redis master pod) | `10` | +| `master.readinessProbe.timeoutSeconds` | When the probe times out (redis master pod) | `1` | +| `master.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis master pod) | `1` | +| `master.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | +| `master.priorityClassName` | Redis Master pod priorityClassName | {} | +| `volumePermissions.enabled` | Enable init container that changes volume permissions in the registry (for cases where the default k8s `runAsUser` and `fsUser` values do not work) | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | +| `volumePermissions.image.repository` | Init container volume-permissions image name | `bitnami/minideb` | +| `volumePermissions.image.tag` | Init container volume-permissions image tag | `buster` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `Always` | +| `volumePermissions.resources ` | Init container volume-permissions CPU/Memory resource requests/limits | {} | +| `slave.service.type` | Kubernetes Service type (redis slave) | `ClusterIP` | +| `slave.service.nodePort` | Kubernetes Service nodePort (redis slave) | `nil` | +| `slave.service.annotations` | annotations for redis slave service | {} | +| `slave.service.labels` | Additional labels for redis slave service | {} | +| `slave.service.port` | Kubernetes Service port (redis slave) | `6379` | +| `slave.service.loadBalancerIP` | LoadBalancerIP if Redis slave service type is `LoadBalancer` | `nil` | +| `slave.service.loadBalancerSourceRanges` | loadBalancerSourceRanges if Redis slave service type is `LoadBalancer` | `nil` | +| `slave.command` | Redis slave entrypoint array. The docker image's ENTRYPOINT is used if this is not provided. | `/run.sh` | +| `slave.configmap` | Additional Redis configuration for the slave nodes (this value is evaluated as a template) | `nil` | +| `slave.disableCommands` | Array of Redis commands to disable (slave) | `[FLUSHDB, FLUSHALL]` | +| `slave.extraFlags` | Redis slave additional command line flags | `[]` | +| `slave.livenessProbe.enabled` | Turn on and off liveness probe (redis slave pod) | `true` | +| `slave.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (redis slave pod) | `30` | +| `slave.livenessProbe.periodSeconds` | How often to perform the probe (redis slave pod) | `10` | +| `slave.livenessProbe.timeoutSeconds` | When the probe times out (redis slave pod) | `5` | +| `slave.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis slave pod) | `1` | +| `slave.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | +| `slave.readinessProbe.enabled` | Turn on and off slave.readiness probe (redis slave pod) | `true` | +| `slave.readinessProbe.initialDelaySeconds` | Delay before slave.readiness probe is initiated (redis slave pod) | `5` | +| `slave.readinessProbe.periodSeconds` | How often to perform the probe (redis slave pod) | `10` | +| `slave.readinessProbe.timeoutSeconds` | When the probe times out (redis slave pod) | `10` | +| `slave.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis slave pod) | `1` | +| `slave.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. (redis slave pod) | `5` | +| `slave.persistence.enabled` | Use a PVC to persist data (slave node) | `true` | +| `slave.persistence.path` | Path to mount the volume at, to use other images | `/data` | +| `slave.persistence.subPath` | Subdirectory of the volume to mount at | `""` | +| `slave.persistence.storageClass` | Storage class of backing PVC | `generic` | +| `slave.persistence.accessModes` | Persistent Volume Access Modes | `[ReadWriteOnce]` | +| `slave.persistence.size` | Size of data volume | `8Gi` | +| `slave.persistence.matchLabels` | matchLabels persistent volume selector | `{}` | +| `slave.persistence.matchExpressions` | matchExpressions persistent volume selector | `{}` | +| `slave.statefulset.updateStrategy` | Update strategy for StatefulSet | onDelete | +| `slave.statefulset.rollingUpdatePartition` | Partition update strategy | `nil` | +| `slave.podLabels` | Additional labels for Redis slave pod | `master.podLabels` | +| `slave.podAnnotations` | Additional annotations for Redis slave pod | `master.podAnnotations` | +| `slave.schedulerName` | Name of an alternate scheduler | `nil` | +| `slave.resources` | Redis slave CPU/Memory resource requests/limits | `{}` | +| `slave.affinity` | Enable node/pod affinity for slaves | {} | +| `slave.priorityClassName` | Redis Slave pod priorityClassName | {} | +| `sentinel.enabled` | Enable sentinel containers | `false` | +| `sentinel.usePassword` | Use password for sentinel containers | `true` | +| `sentinel.masterSet` | Name of the sentinel master set | `mymaster` | +| `sentinel.initialCheckTimeout` | Timeout for querying the redis sentinel service for the active sentinel list | `5` | +| `sentinel.quorum` | Quorum for electing a new master | `2` | +| `sentinel.downAfterMilliseconds` | Timeout for detecting a Redis node is down | `60000` | +| `sentinel.failoverTimeout` | Timeout for performing a election failover | `18000` | +| `sentinel.parallelSyncs` | Number of parallel syncs in the cluster | `1` | +| `sentinel.port` | Redis Sentinel port | `26379` | +| `sentinel.configmap` | Additional Redis configuration for the sentinel nodes (this value is evaluated as a template) | `nil` | +| `sentinel.staticID` | Enable static IDs for sentinel replicas (If disabled IDs will be randomly generated on startup) | `false` | +| `sentinel.service.type` | Kubernetes Service type (redis sentinel) | `ClusterIP` | +| `sentinel.service.nodePort` | Kubernetes Service nodePort (redis sentinel) | `nil` | +| `sentinel.service.annotations` | annotations for redis sentinel service | {} | +| `sentinel.service.labels` | Additional labels for redis sentinel service | {} | +| `sentinel.service.redisPort` | Kubernetes Service port for Redis read only operations | `6379` | +| `sentinel.service.sentinelPort` | Kubernetes Service port for Redis sentinel | `26379` | +| `sentinel.service.redisNodePort` | Kubernetes Service node port for Redis read only operations | `` | +| `sentinel.service.sentinelNodePort` | Kubernetes Service node port for Redis sentinel | `` | +| `sentinel.service.loadBalancerIP` | LoadBalancerIP if Redis sentinel service type is `LoadBalancer` | `nil` | +| `sentinel.livenessProbe.enabled` | Turn on and off liveness probe (redis sentinel pod) | `true` | +| `sentinel.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (redis sentinel pod) | `5` | +| `sentinel.livenessProbe.periodSeconds` | How often to perform the probe (redis sentinel container) | `5` | +| `sentinel.livenessProbe.timeoutSeconds` | When the probe times out (redis sentinel container) | `5` | +| `sentinel.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis sentinel container) | `1` | +| `sentinel.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | +| `sentinel.readinessProbe.enabled` | Turn on and off sentinel.readiness probe (redis sentinel pod) | `true` | +| `sentinel.readinessProbe.initialDelaySeconds` | Delay before sentinel.readiness probe is initiated (redis sentinel pod) | `5` | +| `sentinel.readinessProbe.periodSeconds` | How often to perform the probe (redis sentinel pod) | `5` | +| `sentinel.readinessProbe.timeoutSeconds` | When the probe times out (redis sentinel container) | `1` | +| `sentinel.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis sentinel container) | `1` | +| `sentinel.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. (redis sentinel container) | `5` | +| `sentinel.resources` | Redis sentinel CPU/Memory resource requests/limits | `{}` | +| `sentinel.image.registry` | Redis Sentinel Image registry | `docker.io` | +| `sentinel.image.repository` | Redis Sentinel Image name | `bitnami/redis-sentinel` | +| `sentinel.image.tag` | Redis Sentinel Image tag | `{TAG_NAME}` | +| `sentinel.image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `sentinel.image.pullSecrets` | Specify docker-registry secret names as an array | `nil` | +| `sysctlImage.enabled` | Enable an init container to modify Kernel settings | `false` | +| `sysctlImage.command` | sysctlImage command to execute | [] | +| `sysctlImage.registry` | sysctlImage Init container registry | `docker.io` | +| `sysctlImage.repository` | sysctlImage Init container name | `bitnami/minideb` | +| `sysctlImage.tag` | sysctlImage Init container tag | `buster` | +| `sysctlImage.pullPolicy` | sysctlImage Init container pull policy | `Always` | +| `sysctlImage.mountHostSys` | Mount the host `/sys` folder to `/host-sys` | `false` | +| `sysctlImage.resources` | sysctlImage Init container CPU/Memory resource requests/limits | {} | +| `podSecurityPolicy.create` | Specifies whether a PodSecurityPolicy should be created | `false` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```bash +$ helm install my-release \ + --set password=secretpassword \ + stable/redis +``` + +The above command sets the Redis server password to `secretpassword`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +$ helm install my-release -f values.yaml stable/redis +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +> **Note for minikube users**: Current versions of minikube (v0.24.1 at the time of writing) provision `hostPath` persistent volumes that are only writable by root. Using chart defaults cause pod failure for the Redis pod as it attempts to write to the `/bitnami` directory. Consider installing Redis with `--set persistence.enabled=false`. See minikube issue [1990](https://github.com/kubernetes/minikube/issues/1990) for more information. + +## Configuration and installation details + +### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Production configuration + +This chart includes a `values-production.yaml` file where you can find some parameters oriented to production configuration in comparison to the regular `values.yaml`. You can use this file instead of the default one. + +- Number of slaves: +```diff +- cluster.slaveCount: 2 ++ cluster.slaveCount: 3 +``` + +- Enable NetworkPolicy: +```diff +- networkPolicy.enabled: false ++ networkPolicy.enabled: true +``` + +- Start a side-car prometheus exporter: +```diff +- metrics.enabled: false ++ metrics.enabled: true +``` + +### Cluster topologies + +#### Default: Master-Slave + +When installing the chart with `cluster.enabled=true`, it will deploy a Redis master StatefulSet (only one master node allowed) and a Redis slave StatefulSet. The slaves will be read-replicas of the master. Two services will be exposed: + + - Redis Master service: Points to the master, where read-write operations can be performed + - Redis Slave service: Points to the slaves, where only read operations are allowed. + +In case the master crashes, the slaves will wait until the master node is respawned again by the Kubernetes Controller Manager. + +#### Master-Slave with Sentinel + +When installing the chart with `cluster.enabled=true` and `sentinel.enabled=true`, it will deploy a Redis master StatefulSet (only one master allowed) and a Redis slave StatefulSet. In this case, the pods will contain en extra container with Redis Sentinel. This container will form a cluster of Redis Sentinel nodes, which will promote a new master in case the actual one fails. In addition to this, only one service is exposed: + + - Redis service: Exposes port 6379 for Redis read-only operations and port 26379 for accesing Redis Sentinel. + +For read-only operations, access the service using port 6379. For write operations, it's necessary to access the Redis Sentinel cluster and query the current master using the command below (using redis-cli or similar: + +``` +SENTINEL get-master-addr-by-name +``` +This command will return the address of the current master, which can be accessed from inside the cluster. + +In case the current master crashes, the Sentinel containers will elect a new master node. + +### Using password file +To use a password file for Redis you need to create a secret containing the password. + +> *NOTE*: It is important that the file with the password must be called `redis-password` + +And then deploy the Helm Chart using the secret name as parameter: + +```console +usePassword=true +usePasswordFile=true +existingSecret=redis-password-file +sentinels.enabled=true +metrics.enabled=true +``` + +### Metrics + +The chart optionally can start a metrics exporter for [prometheus](https://prometheus.io). The metrics endpoint (port 9121) is exposed in the service. Metrics can be scraped from within the cluster using something similar as the described in the [example Prometheus scrape configuration](https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml). If metrics are to be scraped from outside the cluster, the Kubernetes API proxy can be utilized to access the endpoint. + +### Host Kernel Settings +Redis may require some changes in the kernel of the host machine to work as expected, in particular increasing the `somaxconn` value and disabling transparent huge pages. +To do so, you can set up a privileged initContainer with the `sysctlImage` config values, for example: +``` +sysctlImage: + enabled: true + mountHostSys: true + command: + - /bin/sh + - -c + - |- + install_packages procps + sysctl -w net.core.somaxconn=10000 + echo never > /host-sys/kernel/mm/transparent_hugepage/enabled +``` + +Alternatively, for Kubernetes 1.12+ you can set `securityContext.sysctls` which will configure sysctls for master and slave pods. Example: + +```yaml +securityContext: + sysctls: + - name: net.core.somaxconn + value: "10000" +``` + +Note that this will not disable transparent huge tables. + +## Persistence + +By default, the chart mounts a [Persistent Volume](http://kubernetes.io/docs/user-guide/persistent-volumes/) at the `/data` path. The volume is created using dynamic volume provisioning. If a Persistent Volume Claim already exists, specify it during installation. + +### Existing PersistentVolumeClaim + +1. Create the PersistentVolume +2. Create the PersistentVolumeClaim +3. Install the chart + +```bash +$ helm install my-release --set persistence.existingClaim=PVC_NAME stable/redis +``` + +## NetworkPolicy + +To enable network policy for Redis, install +[a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), +and set `networkPolicy.enabled` to `true`. + +For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting +the DefaultDeny namespace annotation. Note: this will enforce policy for _all_ pods in the namespace: + + kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" + +With NetworkPolicy enabled, only pods with the generated client label will be +able to connect to Redis. This label will be displayed in the output +after a successful install. + +With `networkPolicy.ingressNSMatchLabels` pods from other namespaces can connect to redis. Set `networkPolicy.ingressNSPodMatchLabels` to match pod labels in matched namespace. For example, for a namespace labeled `redis=external` and pods in that namespace labeled `redis-client=true` the fields should be set: + +``` +networkPolicy: + enabled: true + ingressNSMatchLabels: + redis: external + ingressNSPodMatchLabels: + redis-client: true +``` + +## 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 10.0.0 + +For releases with `usePassword: true`, the value `sentinel.usePassword` controls whether the password authentication also applies to the sentinel port. This defaults to `true` for a secure configuration, however it is possible to disable to account for the following cases: +* Using a version of redis-sentinel prior to `5.0.1` where the authentication feature was introduced. +* Where redis clients need to be updated to support sentinel authentication. + +If using a master/slave topology, or with `usePassword: false`, no action is required. + +### To 8.0.18 + +For releases with `metrics.enabled: true` the default tag for the exporter image is now `v1.x.x`. This introduces many changes including metrics names. You'll want to use [this dashboard](https://github.com/oliver006/redis_exporter/blob/master/contrib/grafana_prometheus_redis_dashboard.json) now. Please see the [redis_exporter github page](https://github.com/oliver006/redis_exporter#upgrading-from-0x-to-1x) for more details. + +### To 7.0.0 + +This version causes a change in the Redis Master StatefulSet definition, so the command helm upgrade would not work out of the box. As an alternative, one of the following could be done: + + - Recommended: Create a clone of the Redis Master PVC (for example, using projects like [this one](https://github.com/edseymour/pvc-transfer)). Then launch a fresh release reusing this cloned PVC. + + ``` + helm install my-release stable/redis --set persistence.existingClaim= + ``` + + - Alternative (not recommended, do at your own risk): `helm delete --purge` does not remove the PVC assigned to the Redis Master StatefulSet. As a consequence, the following commands can be done to upgrade the release + + ``` + helm delete --purge + helm install stable/redis + ``` + +Previous versions of the chart were not using persistence in the slaves, so this upgrade would add it to them. Another important change is that no values are inherited from master to slaves. For example, in 6.0.0 `slaves.readinessProbe.periodSeconds`, if empty, would be set to `master.readinessProbe.periodSeconds`. This approach lacked transparency and was difficult to maintain. From now on, all the slave parameters must be configured just as it is done with the masters. + +Some values have changed as well: + + - `master.port` and `slave.port` have been changed to `redisPort` (same value for both master and slaves) + - `master.securityContext` and `slave.securityContext` have been changed to `securityContext`(same values for both master and slaves) + +By default, the upgrade will not change the cluster topology. In case you want to use Redis Sentinel, you must explicitly set `sentinel.enabled` to `true`. + +### To 6.0.0 + +Previous versions of the chart were using an init-container to change the permissions of the volumes. This was done in case the `securityContext` directive in the template was not enough for that (for example, with cephFS). In this new version of the chart, this container is disabled by default (which should not affect most of the deployments). If your installation still requires that init container, execute `helm upgrade` with the `--set volumePermissions.enabled=true`. + +### To 5.0.0 + +The default image in this release may be switched out for any image containing the `redis-server` +and `redis-cli` binaries. If `redis-server` is not the default image ENTRYPOINT, `master.command` +must be specified. + +#### Breaking changes +- `master.args` and `slave.args` are removed. Use `master.command` or `slave.command` instead in order to override the image entrypoint, or `master.extraFlags` to pass additional flags to `redis-server`. +- `disableCommands` is now interpreted as an array of strings instead of a string of comma separated values. +- `master.persistence.path` now defaults to `/data`. + +### 4.0.0 + +This version removes the `chart` label from the `spec.selector.matchLabels` +which is immutable since `StatefulSet apps/v1beta2`. It has been inadvertently +added, causing any subsequent upgrade to fail. See https://github.com/helm/charts/issues/7726. + +It also fixes https://github.com/helm/charts/issues/7726 where a deployment `extensions/v1beta1` can not be upgraded if `spec.selector` is not explicitly set. + +Finally, it fixes https://github.com/helm/charts/issues/7803 by removing mutable labels in `spec.VolumeClaimTemplate.metadata.labels` so that it is upgradable. + +In order to upgrade, delete the Redis StatefulSet before upgrading: +```bash +$ kubectl delete statefulsets.apps --cascade=false my-release-redis-master +``` +And edit the Redis slave (and metrics if enabled) deployment: +```bash +kubectl patch deployments my-release-redis-slave --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]' +kubectl patch deployments my-release-redis-metrics --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]' +``` + +## Notable changes + +### 9.0.0 +The metrics exporter has been changed from a separate deployment to a sidecar container, due to the latest changes in the Redis exporter code. Check the [official page](https://github.com/oliver006/redis_exporter/) for more information. The metrics container image was changed from oliver006/redis_exporter to bitnami/redis-exporter (Bitnami's maintained package of oliver006/redis_exporter). + +### 7.0.0 +In order to improve the performance in case of slave failure, we added persistence to the read-only slaves. That means that we moved from Deployment to StatefulSets. This should not affect upgrades from previous versions of the chart, as the deployments did not contain any persistence at all. + +This version also allows enabling Redis Sentinel containers inside of the Redis Pods (feature disabled by default). In case the master crashes, a new Redis node will be elected as master. In order to query the current master (no redis master service is exposed), you need to query first the Sentinel cluster. Find more information [in this section](#master-slave-with-sentinel). From d26b1dce463efd2765109fb67f5e39f2be283b6e Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Fri, 13 Mar 2020 09:37:37 +0800 Subject: [PATCH 03/15] Remove unneeded OWNERS file for 3rd party charts --- infra/charts/feast/charts/grafana/OWNERS | 8 -------- infra/charts/feast/charts/kafka/OWNERS | 4 ---- infra/charts/feast/charts/postgresql/OWNERS | 18 ------------------ infra/charts/feast/charts/prometheus/OWNERS | 6 ------ infra/charts/feast/charts/redis/OWNERS | 18 ------------------ 5 files changed, 54 deletions(-) delete mode 100644 infra/charts/feast/charts/grafana/OWNERS delete mode 100644 infra/charts/feast/charts/kafka/OWNERS delete mode 100644 infra/charts/feast/charts/postgresql/OWNERS delete mode 100644 infra/charts/feast/charts/prometheus/OWNERS delete mode 100644 infra/charts/feast/charts/redis/OWNERS diff --git a/infra/charts/feast/charts/grafana/OWNERS b/infra/charts/feast/charts/grafana/OWNERS deleted file mode 100644 index 29b8299822a..00000000000 --- a/infra/charts/feast/charts/grafana/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -approvers: -- zanhsieh -- rtluckie -- maorfr -reviewers: -- zanhsieh -- rtluckie -- maorfr diff --git a/infra/charts/feast/charts/kafka/OWNERS b/infra/charts/feast/charts/kafka/OWNERS deleted file mode 100644 index 0ed92ba2d1a..00000000000 --- a/infra/charts/feast/charts/kafka/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -approvers: -- benjigoldberg -reviewers: -- benjigoldberg diff --git a/infra/charts/feast/charts/postgresql/OWNERS b/infra/charts/feast/charts/postgresql/OWNERS deleted file mode 100644 index 5fbcd3961a1..00000000000 --- a/infra/charts/feast/charts/postgresql/OWNERS +++ /dev/null @@ -1,18 +0,0 @@ -approvers: -- prydonius -- tompizmor -- sameersbn -- carrodher -- javsalgar -- juan131 -- desaintmartin -- miguelaeh -reviewers: -- prydonius -- tompizmor -- sameersbn -- carrodher -- javsalgar -- juan131 -- desaintmartin -- miguelaeh diff --git a/infra/charts/feast/charts/prometheus/OWNERS b/infra/charts/feast/charts/prometheus/OWNERS deleted file mode 100644 index 8e4de5ee70e..00000000000 --- a/infra/charts/feast/charts/prometheus/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -approvers: -- gianrubio -- zanhsieh -reviewers: -- gianrubio -- zanhsieh diff --git a/infra/charts/feast/charts/redis/OWNERS b/infra/charts/feast/charts/redis/OWNERS deleted file mode 100644 index 0fb15b4266e..00000000000 --- a/infra/charts/feast/charts/redis/OWNERS +++ /dev/null @@ -1,18 +0,0 @@ -approvers: -- carrodher -- javsalgar -- desaintmartin -- juan131 -- prydonius -- sameersbn -- tompizmor -- miguelaeh -reviewers: -- carrodher -- javsalgar -- desaintmartin -- juan131 -- prydonius -- sameersbn -- tompizmor -- miguelaeh From 392fad1910bf5b717125caaaad5f398088337c6e Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Fri, 13 Mar 2020 09:43:48 +0800 Subject: [PATCH 04/15] Move .helmdocsignore to correct location helm-docs look for it in repo root folder --- .helmdocsignore | 6 ++++++ infra/charts/feast/.helmdocsignore | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 .helmdocsignore delete mode 100644 infra/charts/feast/.helmdocsignore diff --git a/.helmdocsignore b/.helmdocsignore new file mode 100644 index 00000000000..8f246bffece --- /dev/null +++ b/.helmdocsignore @@ -0,0 +1,6 @@ +infra/charts/feast/charts/postgresql +infra/charts/feast/charts/kafka +infra/charts/feast/charts/redis +infra/charts/feast/charts/prometheus-statsd-exporter +infra/charts/feast/charts/prometheus +infra/charts/feast/charts/grafana diff --git a/infra/charts/feast/.helmdocsignore b/infra/charts/feast/.helmdocsignore deleted file mode 100644 index 21848990474..00000000000 --- a/infra/charts/feast/.helmdocsignore +++ /dev/null @@ -1,6 +0,0 @@ -charts/postgresql -charts/kafka -charts/redis -charts/prometheus-statsd-exporter -charts/prometheus -charts/grafana From c54faf4a4bdae82aba161d50ec50afdaa5465782 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Fri, 13 Mar 2020 10:00:43 +0800 Subject: [PATCH 05/15] Add test prefix for projects created in helm test --- .../charts/feast/templates/tests/test-feast-batch-serving.yaml | 2 +- .../charts/feast/templates/tests/test-feast-online-serving.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml b/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml index 7c4f2075b9b..2fb8ff25c95 100644 --- a/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml +++ b/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml @@ -45,7 +45,7 @@ spec: pd.set_option("display.max_columns", 10) client = Client(core_url=os.getenv("FEAST_CORE_ADDR"), serving_url=os.getenv("FEAST_SERVING_ADDR")) - project = f"project_{int(time.time() / 3600)}" + project = f"testproject_{int(time.time() / 3600)}" if project not in client.list_projects(): client.create_project(project) client.set_project(project) diff --git a/infra/charts/feast/templates/tests/test-feast-online-serving.yaml b/infra/charts/feast/templates/tests/test-feast-online-serving.yaml index 292bb497130..f0db3801172 100644 --- a/infra/charts/feast/templates/tests/test-feast-online-serving.yaml +++ b/infra/charts/feast/templates/tests/test-feast-online-serving.yaml @@ -45,7 +45,7 @@ spec: pd.set_option("display.max_columns", 10) client = Client(core_url=os.getenv("FEAST_CORE_ADDR"), serving_url=os.getenv("FEAST_SERVING_ADDR")) - project = f"project_{int(time.time() / 3600)}" + project = f"testproject_{int(time.time() / 3600)}" if project not in client.list_projects(): client.create_project(project) client.set_project(project) From 2a728dbaa714c9cd4f24aab76111acbfae618644 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Fri, 13 Mar 2020 10:07:03 +0800 Subject: [PATCH 06/15] Add missing kafka port in example feast stream config Incorrectly swapped resources requests and limit --- infra/charts/feast/README.md | 6 +++--- infra/charts/feast/README.md.gotmpl | 6 +++--- infra/charts/feast/values-dataflow-runner.yaml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 1b3f5746727..3affaa2ce10 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -195,7 +195,7 @@ feast-core: feast: stream: options: - bootstrapServers: + bootstrapServers: jobs: runner: DataflowRunner options: @@ -355,9 +355,9 @@ to set the minimum and maximum heap. This is an example reasonable value to set feast-online-serving: javaOpts: "-Xms2048m -Xmx2048m" resources: - requests: - memory: "4096Mi" limits: + memory: "4096Mi" + requests: memory: "2048Mi" cpu: "2" ``` diff --git a/infra/charts/feast/README.md.gotmpl b/infra/charts/feast/README.md.gotmpl index 269b0517006..83e009418c2 100644 --- a/infra/charts/feast/README.md.gotmpl +++ b/infra/charts/feast/README.md.gotmpl @@ -182,7 +182,7 @@ feast-core: feast: stream: options: - bootstrapServers: + bootstrapServers: jobs: runner: DataflowRunner options: @@ -342,9 +342,9 @@ to set the minimum and maximum heap. This is an example reasonable value to set feast-online-serving: javaOpts: "-Xms2048m -Xmx2048m" resources: - requests: - memory: "4096Mi" limits: + memory: "4096Mi" + requests: memory: "2048Mi" cpu: "2" ``` diff --git a/infra/charts/feast/values-dataflow-runner.yaml b/infra/charts/feast/values-dataflow-runner.yaml index a0cb477c6ff..3cdf5cc78ed 100644 --- a/infra/charts/feast/values-dataflow-runner.yaml +++ b/infra/charts/feast/values-dataflow-runner.yaml @@ -5,7 +5,7 @@ feast-core: feast: stream: options: - bootstrapServers: + bootstrapServers: jobs: runner: DataflowRunner options: From 9976aa0d06e6fa87b48cd8b6cef15b5e0bc277e3 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Fri, 13 Mar 2020 11:13:17 +0800 Subject: [PATCH 07/15] Typo --- infra/charts/feast/README.md | 2 +- infra/charts/feast/README.md.gotmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 3affaa2ce10..eb50ee64dee 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -6,7 +6,7 @@ Feature store for machine learning. Current chart version is `0.4.6` ## TL;DR; ```bash -# Install Feast with with Online Serving and Beam DirectRunner +# Install Feast with Online Serving and Beam DirectRunner helm repo add feast-charts https://feast-charts.storage.googleapis.com helm repo update helm install --name myrelease feast-charts/feast diff --git a/infra/charts/feast/README.md.gotmpl b/infra/charts/feast/README.md.gotmpl index 83e009418c2..aca69c8150d 100644 --- a/infra/charts/feast/README.md.gotmpl +++ b/infra/charts/feast/README.md.gotmpl @@ -5,7 +5,7 @@ ## TL;DR; ```bash -# Install Feast with with Online Serving and Beam DirectRunner +# Install Feast with Online Serving and Beam DirectRunner helm repo add feast-charts https://feast-charts.storage.googleapis.com helm repo update helm install --name myrelease feast-charts/feast From 4232679f23056c704126bcd0b83fcd6018695344 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Tue, 28 Apr 2020 23:51:43 +0800 Subject: [PATCH 08/15] Add application-secret.yaml, make it optional to use feast-core.postgresql.existingSecret, use JAVA_TOOL_OPTIONS instead of JAVA_OPTS - Also adjust CPU request and memory limit for test pods to fit the actual usage --- infra/charts/feast/Chart.yaml | 2 +- infra/charts/feast/README.md | 6 +++--- infra/charts/feast/README.md.gotmpl | 4 ++-- .../charts/feast/charts/feast-core/README.md | 8 +++++--- .../feast-core/templates/deployment.yaml | 20 ++++++++++++++++--- .../charts/feast-core/templates/secret.yaml | 15 ++++++++++++++ .../feast/charts/feast-core/values.yaml | 12 ++++++++--- .../feast/charts/feast-serving/README.md | 8 +++++--- .../feast-serving/templates/deployment.yaml | 13 +++++++++++- .../feast-serving/templates/secret.yaml | 15 ++++++++++++++ .../feast/charts/feast-serving/values.yaml | 14 +++++++++---- .../tests/test-feast-batch-serving.yaml | 4 +++- .../tests/test-feast-online-serving.yaml | 5 ++++- 13 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 infra/charts/feast/charts/feast-core/templates/secret.yaml create mode 100644 infra/charts/feast/charts/feast-serving/templates/secret.yaml diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index c58ad2a1529..2dbbef84eb8 100644 --- a/infra/charts/feast/Chart.yaml +++ b/infra/charts/feast/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 description: Feature store for machine learning. name: feast -version: 0.4.6 +version: 0.4.7 diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index eb50ee64dee..8bbe7990719 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -1,7 +1,7 @@ feast ===== -Feature store for machine learning. Current chart version is `0.4.6` +Feature store for machine learning. Current chart version is `0.4.7` ## TL;DR; @@ -28,8 +28,8 @@ dependencies so end users are not overwhelmed with the available configuration. | Name | Version | |------|---------| -| [Feast Core](./charts/feast-core/README.md) | 0.4.6 | -| [Feast Serving](./charts/feast-serving/README.md) | 0.4.6 | +| [Feast Core](./charts/feast-core/README.md) | 0.4.7 | +| [Feast Serving](./charts/feast-serving/README.md) | 0.4.7 | | [Postgresql](./charts/postgresql/README.md) | 8.6.1 | | [Kafka](./charts/kafka/README.md) | 0.20.8 | | [Redis](./charts/redis/README.md) | 10.5.6 | diff --git a/infra/charts/feast/README.md.gotmpl b/infra/charts/feast/README.md.gotmpl index aca69c8150d..7312b3186ea 100644 --- a/infra/charts/feast/README.md.gotmpl +++ b/infra/charts/feast/README.md.gotmpl @@ -27,8 +27,8 @@ dependencies so end users are not overwhelmed with the available configuration. | Name | Version | |------|---------| -| [Feast Core](./charts/feast-core/README.md) | 0.4.6 | -| [Feast Serving](./charts/feast-serving/README.md) | 0.4.6 | +| [Feast Core](./charts/feast-core/README.md) | 0.4.7 | +| [Feast Serving](./charts/feast-serving/README.md) | 0.4.7 | | [Postgresql](./charts/postgresql/README.md) | 8.6.1 | | [Kafka](./charts/kafka/README.md) | 0.20.8 | | [Redis](./charts/redis/README.md) | 10.5.6 | diff --git a/infra/charts/feast/charts/feast-core/README.md b/infra/charts/feast/charts/feast-core/README.md index f82b4654b17..64c18787ff4 100644 --- a/infra/charts/feast/charts/feast-core/README.md +++ b/infra/charts/feast/charts/feast-core/README.md @@ -12,13 +12,15 @@ Current chart version is `0.4.6` | Key | Type | Default | Description | |-----|------|---------|-------------| -| "application-override.yaml" | object | `{}` | [Configuration override](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml) for Feast Core | +| "application-override.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | +| "application-secret.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml` | +| envOverrides | object | `{}` | Extra environment variables to set | | gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | | gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | | gcpServiceAccount.existingSecret.name | string | `"feast-gcp-service-account"` | Name of the existing secret containing the service account | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"gcr.io/kf-feast/feast-core"` | Docker image repository | -| image.tag | string | `"0.4.6"` | Image tag | +| image.tag | string | `"0.4.7"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | @@ -36,7 +38,7 @@ Current chart version is `0.4.6` | ingress.http.https.enabled | bool | `true` | Flag to enable HTTPS | | ingress.http.https.secretNames | object | `{}` | Map of hostname to TLS secret name | | ingress.http.whitelist | string | `""` | Allowed client IP source ranges | -| javaOpts | string | `nil` | [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). It is advised for better performance to set the min and max heap:
`-Xms2048m -Xmx2048m` | +| javaOpts | string | `nil` | [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). For better performance, it is advised to set the min and max heap:
`-Xms2048m -Xmx2048m` | | livenessProbe.enabled | bool | `true` | Flag to enabled the probe | | livenessProbe.failureThreshold | int | `5` | Min consecutive failures for the probe to be considered failed | | livenessProbe.initialDelaySeconds | int | `60` | Delay before the probe is initiated | diff --git a/infra/charts/feast/charts/feast-core/templates/deployment.yaml b/infra/charts/feast/charts/feast-core/templates/deployment.yaml index 70d60cd89b7..9e3ce058d39 100644 --- a/infra/charts/feast/charts/feast-core/templates/deployment.yaml +++ b/infra/charts/feast/charts/feast-core/templates/deployment.yaml @@ -38,6 +38,9 @@ spec: - name: {{ template "feast-core.fullname" . }}-config configMap: name: {{ template "feast-core.fullname" . }} + - name: {{ template "feast-core.fullname" . }}-secret + secret: + secretName: {{ template "feast-core.fullname" . }} {{- if .Values.gcpServiceAccount.enabled }} - name: {{ template "feast-core.fullname" . }}-gcp-service-account secret: @@ -52,6 +55,9 @@ spec: volumeMounts: - name: {{ template "feast-core.fullname" . }}-config mountPath: /etc/feast + - name: {{ template "feast-core.fullname" . }}-secret + mountPath: /etc/secrets/feast + readOnly: true {{- if .Values.gcpServiceAccount.enabled }} - name: {{ template "feast-core.fullname" . }}-gcp-service-account mountPath: /etc/secrets/google @@ -63,11 +69,14 @@ spec: value: {{ .Values.logType | quote }} - name: LOG_LEVEL value: {{ .Values.logLevel | quote }} + + {{- if .Values.postgresql.existingSecret }} - name: SPRING_DATASOURCE_PASSWORD valueFrom: secretKeyRef: - name: {{ .Values.postgresql.existingSecret | default (printf "%s-postgresql" .Release.Name) }} + name: {{ .Values.postgresql.existingSecret }} key: postgresql-password + {{- end }} {{- if .Values.gcpServiceAccount.enabled }} - name: GOOGLE_APPLICATION_CREDENTIALS @@ -80,15 +89,20 @@ spec: {{- end }} {{- if .Values.javaOpts }} - - name: JAVA_OPTS + - name: JAVA_TOOL_OPTIONS value: {{ .Values.javaOpts }} {{- end }} + {{- range $key, $value := .Values.envOverrides }} + - name: {{ printf "%s" $key | replace "." "_" | upper | quote }} + value: {{ $value | quote }} + {{- end }} + command: - java - -jar - /opt/feast/feast-core.jar - - --spring.config.additional-location=/etc/feast/application-default-postgresql.yaml,/etc/feast/application-default-kafka.yaml,/etc/feast/application-default-statsd.yaml,/etc/feast/application-override.yaml + - --spring.config.additional-location=/etc/feast/application-default-postgresql.yaml,/etc/feast/application-default-kafka.yaml,/etc/feast/application-default-statsd.yaml,/etc/secrets/feast/application-secret.yaml,/etc/feast/application-override.yaml ports: - name: http containerPort: {{ .Values.service.http.targetPort }} diff --git a/infra/charts/feast/charts/feast-core/templates/secret.yaml b/infra/charts/feast/charts/feast-core/templates/secret.yaml new file mode 100644 index 00000000000..dd33e2dd487 --- /dev/null +++ b/infra/charts/feast/charts/feast-core/templates/secret.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "feast-core.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "feast-core.name" . }} + component: core + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +stringData: + application-secret.yaml: | +{{- toYaml (index .Values "application-secret.yaml") | nindent 4 }} diff --git a/infra/charts/feast/charts/feast-core/values.yaml b/infra/charts/feast/charts/feast-core/values.yaml index a2c3f2d00af..722fe9d6d8a 100644 --- a/infra/charts/feast/charts/feast-core/values.yaml +++ b/infra/charts/feast/charts/feast-core/values.yaml @@ -5,13 +5,16 @@ image: # image.repository -- Docker image repository repository: gcr.io/kf-feast/feast-core # image.tag -- Image tag - tag: 0.4.6 + tag: 0.4.7 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent -# "application-override.yaml" -- [Configuration override](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml) for Feast Core +# "application-override.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` application-override.yaml: {} +# "application-secret.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml` +application-secret.yaml: {} + gcpServiceAccount: # gcpServiceAccount.enabled -- Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key enabled: false @@ -25,7 +28,7 @@ postgresql: # postgresql.existingSecret -- Existing secret to use for authenticating to Postgres existingSecret: -# javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). It is advised for better performance to set the min and max heap:
`-Xms2048m -Xmx2048m` +# javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). For better performance, it is advised to set the min and max heap:
`-Xms2048m -Xmx2048m` javaOpts: # logType -- Log format, either `JSON` or `Console` @@ -130,3 +133,6 @@ resources: {} # nodeSelector -- Node labels for pod assignment nodeSelector: {} + +# envOverrides -- Extra environment variables to set +envOverrides: {} \ No newline at end of file diff --git a/infra/charts/feast/charts/feast-serving/README.md b/infra/charts/feast/charts/feast-serving/README.md index 99b0e783874..387a3952031 100644 --- a/infra/charts/feast/charts/feast-serving/README.md +++ b/infra/charts/feast/charts/feast-serving/README.md @@ -12,14 +12,16 @@ Current chart version is `0.4.6` | Key | Type | Default | Description | |-----|------|---------|-------------| -| "application-override.yaml" | object | `{}` | [Configuration override](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml) for Feast Serving. Note that setting `store.config-path` is not necessary since this chart will set it to where `store.yaml` is mounted. | +| "application-override.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | +| "application-secret.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml` | | "store.yaml" | object | `{}` | Store [config](https://github.com/gojek/feast/blob/master/protos/feast/core/Store.proto#L32) in yaml format. This is an [example](https://github.com/gojek/feast/blob/v0.4-branch/serving/sample_redis_config.yml) for Redis. | +| envOverrides | object | `{}` | Extra environment variables to set | | gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | | gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | | gcpServiceAccount.existingSecret.name | string | `"feast-gcp-service-account"` | Name of the existing secret containing the service account | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"gcr.io/kf-feast/feast-serving"` | Docker image repository | -| image.tag | string | `"0.4.6"` | Image tag | +| image.tag | string | `"0.4.7"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | @@ -37,7 +39,7 @@ Current chart version is `0.4.6` | ingress.http.https.enabled | bool | `true` | Flag to enable HTTPS | | ingress.http.https.secretNames | object | `{}` | Map of hostname to TLS secret name | | ingress.http.whitelist | string | `""` | Allowed client IP source ranges | -| javaOpts | string | `nil` | [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). It is advised for better performance to set the min and max heap:
`-Xms2048m -Xmx2048m` | +| javaOpts | string | `nil` | [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). For better performance, it is advised to set the min and max heap:
`-Xms2048m -Xmx2048m` | | livenessProbe.enabled | bool | `true` | Flag to enabled the probe | | livenessProbe.failureThreshold | int | `5` | Min consecutive failures for the probe to be considered failed | | livenessProbe.initialDelaySeconds | int | `60` | Delay before the probe is initiated | diff --git a/infra/charts/feast/charts/feast-serving/templates/deployment.yaml b/infra/charts/feast/charts/feast-serving/templates/deployment.yaml index 9930ac441d0..db8348bd722 100644 --- a/infra/charts/feast/charts/feast-serving/templates/deployment.yaml +++ b/infra/charts/feast/charts/feast-serving/templates/deployment.yaml @@ -38,6 +38,9 @@ spec: - name: {{ template "feast-serving.fullname" . }}-config configMap: name: {{ template "feast-serving.fullname" . }} + - name: {{ template "feast-serving.fullname" . }}-secret + secret: + secretName: {{ template "feast-serving.fullname" . }} {{- if .Values.gcpServiceAccount.enabled }} - name: {{ template "feast-serving.fullname" . }}-gcp-service-account secret: @@ -52,6 +55,9 @@ spec: volumeMounts: - name: {{ template "feast-serving.fullname" . }}-config mountPath: /etc/feast + - name: {{ template "feast-serving.fullname" . }}-secret + mountPath: /etc/secrets/feast + readOnly: true {{- if .Values.gcpServiceAccount.enabled }} - name: {{ template "feast-serving.fullname" . }}-gcp-service-account mountPath: /etc/secrets/google @@ -75,10 +81,15 @@ spec: {{- end }} {{- if .Values.javaOpts }} - - name: JAVA_OPTS + - name: JAVA_TOOL_OPTIONS value: {{ .Values.javaOpts }} {{- end }} + {{- range $key, $value := .Values.envOverrides }} + - name: {{ printf "%s" $key | replace "." "_" | upper | quote }} + value: {{ $value | quote }} + {{- end }} + command: - java - -jar diff --git a/infra/charts/feast/charts/feast-serving/templates/secret.yaml b/infra/charts/feast/charts/feast-serving/templates/secret.yaml new file mode 100644 index 00000000000..2ccbccfcf7b --- /dev/null +++ b/infra/charts/feast/charts/feast-serving/templates/secret.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "feast-serving.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "feast-serving.name" . }} + component: serving + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +stringData: + application-secret.yaml: | +{{- toYaml (index .Values "application-secret.yaml") | nindent 4 }} diff --git a/infra/charts/feast/charts/feast-serving/values.yaml b/infra/charts/feast/charts/feast-serving/values.yaml index 9108e706abc..8ddc27aa573 100644 --- a/infra/charts/feast/charts/feast-serving/values.yaml +++ b/infra/charts/feast/charts/feast-serving/values.yaml @@ -5,16 +5,19 @@ image: # image.repository -- Docker image repository repository: gcr.io/kf-feast/feast-serving # image.tag -- Image tag - tag: 0.4.6 + tag: 0.4.7 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent -# "store.yaml" -- Store [config](https://github.com/gojek/feast/blob/master/protos/feast/core/Store.proto#L32) in yaml format. This is an [example](https://github.com/gojek/feast/blob/v0.4-branch/serving/sample_redis_config.yml) for Redis. +# "store.yaml" -- Store [config](https://github.com/gojek/feast/blob/master/protos/feast/core/Store.proto#L32) in yaml format. This is an [example](https://github.com/gojek/feast/blob/v0.4-branch/serving/sample_redis_config.yml) for Redis store.yaml: {} -# "application-override.yaml" -- [Configuration override](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml) for Feast Serving. Note that setting `store.config-path` is not necessary since this chart will set it to where `store.yaml` is mounted. +# "application-override.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` application-override.yaml: {} +# "application-secret.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml` +application-secret.yaml: {} + gcpServiceAccount: # gcpServiceAccount.enabled -- Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key # Cloud service account JSON key file. @@ -25,7 +28,7 @@ gcpServiceAccount: # gcpServiceAccount.existingSecret.key -- Key in the secret data (file name of the service account) key: credentials.json -# javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). It is advised for better performance to set the min and max heap:
`-Xms2048m -Xmx2048m` +# javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). For better performance, it is advised to set the min and max heap:
`-Xms2048m -Xmx2048m` javaOpts: # logType -- Log format, either `JSON` or `Console` @@ -130,3 +133,6 @@ resources: {} # nodeSelector -- Node labels for pod assignment nodeSelector: {} + +# envOverrides -- Extra environment variables to set +envOverrides: {} \ No newline at end of file diff --git a/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml b/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml index 2fb8ff25c95..54173021d3b 100644 --- a/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml +++ b/infra/charts/feast/templates/tests/test-feast-batch-serving.yaml @@ -100,7 +100,9 @@ spec: {{- end }} resources: requests: - cpu: 1 + cpu: 500m + memory: 512Mi + limits: memory: 512Mi volumes: {{- if index .Values "feast-batch-serving" "gcpServiceAccount" "enabled" }} diff --git a/infra/charts/feast/templates/tests/test-feast-online-serving.yaml b/infra/charts/feast/templates/tests/test-feast-online-serving.yaml index f0db3801172..f9a213aabb8 100644 --- a/infra/charts/feast/templates/tests/test-feast-online-serving.yaml +++ b/infra/charts/feast/templates/tests/test-feast-online-serving.yaml @@ -95,8 +95,11 @@ spec: value: {{ .Release.Name }}-feast-online-serving:6566 resources: requests: - cpu: 1 + cpu: 500m memory: 512Mi + limits: + memory: 512Mi + restartPolicy: Never {{- end }} From c4047bfcd7b0f0c9a9d513949cf3c2c3411240ef Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Wed, 29 Apr 2020 11:57:34 +0800 Subject: [PATCH 09/15] Update README and configuration so it works Feast v0.5, but not Feast v0.4 --- infra/charts/feast/Chart.yaml | 2 +- infra/charts/feast/README.md | 203 +++++++++--------- infra/charts/feast/README.md.gotmpl | 201 ++++++++--------- .../charts/feast/charts/feast-core/Chart.yaml | 2 +- .../charts/feast/charts/feast-core/README.md | 8 +- .../feast/charts/feast-core/values.yaml | 6 +- .../feast/charts/feast-serving/Chart.yaml | 2 +- .../feast/charts/feast-serving/README.md | 9 +- .../feast-serving/templates/configmap.yaml | 33 ++- .../feast/charts/feast-serving/values.yaml | 9 +- .../feast/charts/prometheus/values.yaml | 4 +- infra/charts/feast/requirements.yaml | 6 +- .../tests/test-feast-online-serving.yaml | 2 +- 13 files changed, 243 insertions(+), 244 deletions(-) diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index 2dbbef84eb8..8ce82e4a01d 100644 --- a/infra/charts/feast/Chart.yaml +++ b/infra/charts/feast/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 description: Feature store for machine learning. name: feast -version: 0.4.7 +version: 0.5.0-alpha.1 diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 8bbe7990719..f3ed9a062bd 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -1,15 +1,23 @@ feast ===== -Feature store for machine learning. Current chart version is `0.4.7` +Feature store for machine learning. Current chart version is `0.5.0-alpha.1` ## TL;DR; ```bash -# Install Feast with Online Serving and Beam DirectRunner +# Add Feast Helm chart helm repo add feast-charts https://feast-charts.storage.googleapis.com helm repo update -helm install --name myrelease feast-charts/feast + +# Create secret for Feast database, replace accordingly +kubectl create secret generic feast-postgresql \ + --from-literal=postgresql-password= + +# Install Feast with Online Serving and Beam DirectRunner +helm install --name myrelease feast-charts/feast \ + --set feast-core.postgresql.existingSecret=feast-postgresql \ + --set postgresql.existingSecret=feast-postgresql ``` ## Introduction @@ -28,8 +36,8 @@ dependencies so end users are not overwhelmed with the available configuration. | Name | Version | |------|---------| -| [Feast Core](./charts/feast-core/README.md) | 0.4.7 | -| [Feast Serving](./charts/feast-serving/README.md) | 0.4.7 | +| [Feast Core](./charts/feast-core/README.md) | 0.5.0-alpha.1 | +| [Feast Serving](./charts/feast-serving/README.md) | 0.5.0-alpha.1 | | [Postgresql](./charts/postgresql/README.md) | 8.6.1 | | [Kafka](./charts/kafka/README.md) | 0.20.8 | | [Redis](./charts/redis/README.md) | 10.5.6 | @@ -54,8 +62,21 @@ dependencies so end users are not overwhelmed with the available configuration. ## Configuration and installation details The default configuration will install Feast with Online Serving. Ingestion -of features uses Beam [DirectRunner](https://beam.apache.org/documentation/runners/direct/) -that runs on the same container where Feast Core is running. To test the installation: +of features will use Beam [DirectRunner](https://beam.apache.org/documentation/runners/direct/) +that runs on the same container where Feast Core is running. + +```bash +# Create secret for Feast database, replace accordingly +kubectl create secret generic feast-postgresql \ + --from-literal=postgresql-password= + +# Install Feast with Online Serving and Beam DirectRunner +helm install --name myrelease feast-charts/feast \ + --set feast-core.postgresql.existingSecret=feast-postgresql \ + --set postgresql.existingSecret=feast-postgresql +``` + +In order to test that the installation is successful: ```bash helm test myrelease @@ -67,7 +88,7 @@ PASSED: myrelease-grafana-test RUNNING: myrelease-test-topic-create-consume-produce PASSED: myrelease-test-topic-create-consume-produce -# In order to check the logs from the test +# Once the test completes, to check the logs kubectl logs myrelease-feast-online-serving-test ``` @@ -120,25 +141,32 @@ Use the following Helm values to enable Batch Serving: feast-core: gcpServiceAccount: enabled: true + postgresql: + existingSecret: feast-postgresql feast-batch-serving: enabled: true - store.yaml: - name: bigquery-store - type: BIGQUERY - bigquery_config: - project_id: - dataset_id: - subscriptions: - - project: "*" - name: "*" - version: "*" - application-override.yaml: - feast: - jobs: - staging-location: gs:///staging-location gcpServiceAccount: enabled: true + application-override.yaml: + feast: + active_store: historical + stores: + - name: historical + type: BIGQUERY + config: + project_id: + dataset_id: + staging_location: gs:///feast-staging-location + initial_retry_delay_seconds: 3 + total_timeout_seconds: 21600 + subscriptions: + - name: "*" + project: "*" + version: "*" + +postgresql: + existingSecret: feast-postgresql ``` > To delete the previous release, run `helm delete --purge myrelease` @@ -184,65 +212,77 @@ gcloud compute addresses create \ ``` Use the following Helm values to enable DataflowRuner (and Batch Serving), -replacing the `<*load_balancer_ip*>` tags with the ones reserved above: +replacing the `<*load_balancer_ip*>` tags with the ip addresses reserved above: ```yaml # values-dataflow-runner.yaml feast-core: gcpServiceAccount: enabled: true + postgresql: + existingSecret: feast-postgresql application-override.yaml: feast: stream: options: bootstrapServers: jobs: - runner: DataflowRunner - options: - project: - region: - zone: - tempLocation: - network: - subnetwork: - maxNumWorkers: 1 - autoscalingAlgorithm: THROUGHPUT_BASED - usePublicIps: false - workerMachineType: n1-standard-1 - deadLetterTableSpec: + active_runner: dataflow metrics: host: + runners: + - name: dataflow + type: DataflowRunner + options: + project: + region: + zone: + tempLocation: + network: + subnetwork: + maxNumWorkers: 1 + autoscalingAlgorithm: THROUGHPUT_BASED + usePublicIps: false + workerMachineType: n1-standard-1 + deadLetterTableSpec: feast-online-serving: - store.yaml: - name: redis-store - type: REDIS - redis_config: - host: - port: 6379 - subscriptions: - - project: "*" - name: "*" - version: "*" + application-override.yaml: + feast: + stores: + - name: online + type: REDIS + config: + host: + port: 6379 + subscriptions: + - name: "*" + project: "*" + version: "*" feast-batch-serving: enabled: true - store.yaml: - name: bigquery-store - type: BIGQUERY - bigquery_config: - project_id: - dataset_id: - subscriptions: - - project: "*" - name: "*" - version: "*" - application-override.yaml: - feast: - jobs: - staging-location: gcpServiceAccount: enabled: true + application-override.yaml: + feast: + active_store: historical + stores: + - name: historical + type: BIGQUERY + config: + project_id: + dataset_id: + staging_location: gs:///feast-staging-location + initial_retry_delay_seconds: 3 + total_timeout_seconds: 21600 + subscriptions: + - name: "*" + project: "*" + version: "*" + +postgresql: + existingSecret: feast-postgresql kafka: external: @@ -308,41 +348,6 @@ running features ingestion: https://console.cloud.google.com/dataflow ### Production configuration -#### Secrets management - -The installation examples above automatically create secrets for Postgresql and -Grafana with randomly generated values. However, these secrets are not stable -i.e. running `helm upgrade` will update the secret unintentionally. For -production, the secrets are usually generated first before deployment. In summary, -these are the 3 secrets that Feast requires: - -```bash -kubectl create secret generic feast-postgresql \ - --from-literal=postgresql-password= - -kubectl create secret generic feast-gcp-service-account \ - --from-file=credentials.json - -kubectl create secret generic feast-grafana \ - --from-literal=admin-user=admin \ - --from-literal=admin-password= \ -``` - -With these secrets in place, they can be used like so: -```yaml -# values-existing-secret.yaml -feast-core: - postgresql: - existingSecret: feast-postgresql - -postgresql: - existingSecret: feast-postgresql - -grafana: - admin: - existingSecret: feast-grafana -``` - #### Resources requests The `resources` field in the deployment spec is left empty in the examples. In @@ -356,10 +361,10 @@ feast-online-serving: javaOpts: "-Xms2048m -Xmx2048m" resources: limits: - memory: "4096Mi" + memory: "2048Mi" requests: memory: "2048Mi" - cpu: "2" + cpu: "1" ``` #### High availability @@ -373,5 +378,5 @@ sentinel or additional proxies. ### Documentation development This `README.md` is generated using [helm-docs](https://github.com/norwoodj/helm-docs/). -Run `helm-docs` after changing directory to this folder to regenerate a new `README.md` -when Feast charts or values are modified. \ No newline at end of file +Please run `helm-docs` to regenerate the `README.md` every time `README.md.gotmpl` +or `values.yaml` are updated. diff --git a/infra/charts/feast/README.md.gotmpl b/infra/charts/feast/README.md.gotmpl index 7312b3186ea..ed018e6f814 100644 --- a/infra/charts/feast/README.md.gotmpl +++ b/infra/charts/feast/README.md.gotmpl @@ -5,10 +5,18 @@ ## TL;DR; ```bash -# Install Feast with Online Serving and Beam DirectRunner +# Add Feast Helm chart helm repo add feast-charts https://feast-charts.storage.googleapis.com helm repo update -helm install --name myrelease feast-charts/feast + +# Create secret for Feast database, replace accordingly +kubectl create secret generic feast-postgresql \ + --from-literal=postgresql-password= + +# Install Feast with Online Serving and Beam DirectRunner +helm install --name myrelease feast-charts/feast \ + --set feast-core.postgresql.existingSecret=feast-postgresql \ + --set postgresql.existingSecret=feast-postgresql ``` ## Introduction @@ -27,8 +35,8 @@ dependencies so end users are not overwhelmed with the available configuration. | Name | Version | |------|---------| -| [Feast Core](./charts/feast-core/README.md) | 0.4.7 | -| [Feast Serving](./charts/feast-serving/README.md) | 0.4.7 | +| [Feast Core](./charts/feast-core/README.md) | 0.5.0-alpha.1 | +| [Feast Serving](./charts/feast-serving/README.md) | 0.5.0-alpha.1 | | [Postgresql](./charts/postgresql/README.md) | 8.6.1 | | [Kafka](./charts/kafka/README.md) | 0.20.8 | | [Redis](./charts/redis/README.md) | 10.5.6 | @@ -41,8 +49,21 @@ dependencies so end users are not overwhelmed with the available configuration. ## Configuration and installation details The default configuration will install Feast with Online Serving. Ingestion -of features uses Beam [DirectRunner](https://beam.apache.org/documentation/runners/direct/) -that runs on the same container where Feast Core is running. To test the installation: +of features will use Beam [DirectRunner](https://beam.apache.org/documentation/runners/direct/) +that runs on the same container where Feast Core is running. + +```bash +# Create secret for Feast database, replace accordingly +kubectl create secret generic feast-postgresql \ + --from-literal=postgresql-password= + +# Install Feast with Online Serving and Beam DirectRunner +helm install --name myrelease feast-charts/feast \ + --set feast-core.postgresql.existingSecret=feast-postgresql \ + --set postgresql.existingSecret=feast-postgresql +``` + +In order to test that the installation is successful: ```bash helm test myrelease @@ -54,7 +75,7 @@ PASSED: myrelease-grafana-test RUNNING: myrelease-test-topic-create-consume-produce PASSED: myrelease-test-topic-create-consume-produce -# In order to check the logs from the test +# Once the test completes, to check the logs kubectl logs myrelease-feast-online-serving-test ``` @@ -107,25 +128,32 @@ Use the following Helm values to enable Batch Serving: feast-core: gcpServiceAccount: enabled: true + postgresql: + existingSecret: feast-postgresql feast-batch-serving: enabled: true - store.yaml: - name: bigquery-store - type: BIGQUERY - bigquery_config: - project_id: - dataset_id: - subscriptions: - - project: "*" - name: "*" - version: "*" - application-override.yaml: - feast: - jobs: - staging-location: gs:///staging-location gcpServiceAccount: enabled: true + application-override.yaml: + feast: + active_store: historical + stores: + - name: historical + type: BIGQUERY + config: + project_id: + dataset_id: + staging_location: gs:///feast-staging-location + initial_retry_delay_seconds: 3 + total_timeout_seconds: 21600 + subscriptions: + - name: "*" + project: "*" + version: "*" + +postgresql: + existingSecret: feast-postgresql ``` > To delete the previous release, run `helm delete --purge myrelease` @@ -171,65 +199,77 @@ gcloud compute addresses create \ ``` Use the following Helm values to enable DataflowRuner (and Batch Serving), -replacing the `<*load_balancer_ip*>` tags with the ones reserved above: +replacing the `<*load_balancer_ip*>` tags with the ip addresses reserved above: ```yaml # values-dataflow-runner.yaml feast-core: gcpServiceAccount: enabled: true + postgresql: + existingSecret: feast-postgresql application-override.yaml: feast: stream: options: bootstrapServers: jobs: - runner: DataflowRunner - options: - project: - region: - zone: - tempLocation: - network: - subnetwork: - maxNumWorkers: 1 - autoscalingAlgorithm: THROUGHPUT_BASED - usePublicIps: false - workerMachineType: n1-standard-1 - deadLetterTableSpec: + active_runner: dataflow metrics: host: + runners: + - name: dataflow + type: DataflowRunner + options: + project: + region: + zone: + tempLocation: + network: + subnetwork: + maxNumWorkers: 1 + autoscalingAlgorithm: THROUGHPUT_BASED + usePublicIps: false + workerMachineType: n1-standard-1 + deadLetterTableSpec: feast-online-serving: - store.yaml: - name: redis-store - type: REDIS - redis_config: - host: - port: 6379 - subscriptions: - - project: "*" - name: "*" - version: "*" + application-override.yaml: + feast: + stores: + - name: online + type: REDIS + config: + host: + port: 6379 + subscriptions: + - name: "*" + project: "*" + version: "*" feast-batch-serving: enabled: true - store.yaml: - name: bigquery-store - type: BIGQUERY - bigquery_config: - project_id: - dataset_id: - subscriptions: - - project: "*" - name: "*" - version: "*" - application-override.yaml: - feast: - jobs: - staging-location: gcpServiceAccount: enabled: true + application-override.yaml: + feast: + active_store: historical + stores: + - name: historical + type: BIGQUERY + config: + project_id: + dataset_id: + staging_location: gs:///feast-staging-location + initial_retry_delay_seconds: 3 + total_timeout_seconds: 21600 + subscriptions: + - name: "*" + project: "*" + version: "*" + +postgresql: + existingSecret: feast-postgresql kafka: external: @@ -295,41 +335,6 @@ running features ingestion: https://console.cloud.google.com/dataflow ### Production configuration -#### Secrets management - -The installation examples above automatically create secrets for Postgresql and -Grafana with randomly generated values. However, these secrets are not stable -i.e. running `helm upgrade` will update the secret unintentionally. For -production, the secrets are usually generated first before deployment. In summary, -these are the 3 secrets that Feast requires: - -```bash -kubectl create secret generic feast-postgresql \ - --from-literal=postgresql-password= - -kubectl create secret generic feast-gcp-service-account \ - --from-file=credentials.json - -kubectl create secret generic feast-grafana \ - --from-literal=admin-user=admin \ - --from-literal=admin-password= \ -``` - -With these secrets in place, they can be used like so: -```yaml -# values-existing-secret.yaml -feast-core: - postgresql: - existingSecret: feast-postgresql - -postgresql: - existingSecret: feast-postgresql - -grafana: - admin: - existingSecret: feast-grafana -``` - #### Resources requests The `resources` field in the deployment spec is left empty in the examples. In @@ -343,10 +348,10 @@ feast-online-serving: javaOpts: "-Xms2048m -Xmx2048m" resources: limits: - memory: "4096Mi" + memory: "2048Mi" requests: memory: "2048Mi" - cpu: "2" + cpu: "1" ``` #### High availability @@ -360,5 +365,5 @@ sentinel or additional proxies. ### Documentation development This `README.md` is generated using [helm-docs](https://github.com/norwoodj/helm-docs/). -Run `helm-docs` after changing directory to this folder to regenerate a new `README.md` -when Feast charts or values are modified. \ No newline at end of file +Please run `helm-docs` to regenerate the `README.md` every time `README.md.gotmpl` +or `values.yaml` are updated. diff --git a/infra/charts/feast/charts/feast-core/Chart.yaml b/infra/charts/feast/charts/feast-core/Chart.yaml index e1ee6ea0fd8..5b832943cfe 100644 --- a/infra/charts/feast/charts/feast-core/Chart.yaml +++ b/infra/charts/feast/charts/feast-core/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 description: Feast Core registers feature specifications and manage ingestion jobs. name: feast-core -version: 0.4.6 +version: 0.5.0-alpha.1 diff --git a/infra/charts/feast/charts/feast-core/README.md b/infra/charts/feast/charts/feast-core/README.md index 64c18787ff4..a3daea8c7ff 100644 --- a/infra/charts/feast/charts/feast-core/README.md +++ b/infra/charts/feast/charts/feast-core/README.md @@ -2,7 +2,7 @@ feast-core ========== Feast Core registers feature specifications and manage ingestion jobs. -Current chart version is `0.4.6` +Current chart version is `0.5.0-alpha.1` @@ -12,15 +12,15 @@ Current chart version is `0.4.6` | Key | Type | Default | Description | |-----|------|---------|-------------| -| "application-override.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | -| "application-secret.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml` | +| "application-override.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | +| "application-secret.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify managing the config | | envOverrides | object | `{}` | Extra environment variables to set | | gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | | gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | | gcpServiceAccount.existingSecret.name | string | `"feast-gcp-service-account"` | Name of the existing secret containing the service account | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"gcr.io/kf-feast/feast-core"` | Docker image repository | -| image.tag | string | `"0.4.7"` | Image tag | +| image.tag | string | `"dev"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | diff --git a/infra/charts/feast/charts/feast-core/values.yaml b/infra/charts/feast/charts/feast-core/values.yaml index 722fe9d6d8a..61f5c89e486 100644 --- a/infra/charts/feast/charts/feast-core/values.yaml +++ b/infra/charts/feast/charts/feast-core/values.yaml @@ -5,14 +5,14 @@ image: # image.repository -- Docker image repository repository: gcr.io/kf-feast/feast-core # image.tag -- Image tag - tag: 0.4.7 + tag: dev # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent -# "application-override.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` +# "application-override.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` application-override.yaml: {} -# "application-secret.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml` +# "application-secret.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify managing the config application-secret.yaml: {} gcpServiceAccount: diff --git a/infra/charts/feast/charts/feast-serving/Chart.yaml b/infra/charts/feast/charts/feast-serving/Chart.yaml index f7e526e57d7..7c8e6131cf7 100644 --- a/infra/charts/feast/charts/feast-serving/Chart.yaml +++ b/infra/charts/feast/charts/feast-serving/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 description: Feast Serving serves low-latency latest features and historical batch features. name: feast-serving -version: 0.4.6 +version: 0.5.0-alpha.1 diff --git a/infra/charts/feast/charts/feast-serving/README.md b/infra/charts/feast/charts/feast-serving/README.md index 387a3952031..e5b9d217446 100644 --- a/infra/charts/feast/charts/feast-serving/README.md +++ b/infra/charts/feast/charts/feast-serving/README.md @@ -2,7 +2,7 @@ feast-serving ============= Feast Serving serves low-latency latest features and historical batch features. -Current chart version is `0.4.6` +Current chart version is `0.5.0-alpha.1` @@ -12,16 +12,15 @@ Current chart version is `0.4.6` | Key | Type | Default | Description | |-----|------|---------|-------------| -| "application-override.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | -| "application-secret.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml` | -| "store.yaml" | object | `{}` | Store [config](https://github.com/gojek/feast/blob/master/protos/feast/core/Store.proto#L32) in yaml format. This is an [example](https://github.com/gojek/feast/blob/v0.4-branch/serving/sample_redis_config.yml) for Redis. | +| "application-override.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | +| "application-secret.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify managing the config | | envOverrides | object | `{}` | Extra environment variables to set | | gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | | gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | | gcpServiceAccount.existingSecret.name | string | `"feast-gcp-service-account"` | Name of the existing secret containing the service account | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"gcr.io/kf-feast/feast-serving"` | Docker image repository | -| image.tag | string | `"0.4.7"` | Image tag | +| image.tag | string | `"dev"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | diff --git a/infra/charts/feast/charts/feast-serving/templates/configmap.yaml b/infra/charts/feast/charts/feast-serving/templates/configmap.yaml index 3dbcc192da2..d03f68a3b9b 100644 --- a/infra/charts/feast/charts/feast-serving/templates/configmap.yaml +++ b/infra/charts/feast/charts/feast-serving/templates/configmap.yaml @@ -10,31 +10,24 @@ metadata: release: {{ .Release.Name }} heritage: {{ .Release.Service }} data: - store.yaml: | -{{- if index .Values "store.yaml" }} -{{- toYaml (index .Values "store.yaml") | nindent 4 }} -{{- else }} - name: redis-store - type: REDIS - redis_config: - host: {{ .Release.Name }}-redis-master - port: 6379 - subscriptions: - - name: "*" - project: "*" - version: "*" -{{- end }} - application-default.yaml: | feast: core-host: {{ .Release.Name }}-feast-core - store: - config-path: /etc/feast/store.yaml - jobs: - store-type: REDIS - store-options: + + stores: + - name: online + type: REDIS + config: host: {{ .Release.Name }}-redis-master port: 6379 + subscriptions: + - name: "*" + project: "*" + version: "*" + + job_store: + redis_host: {{ .Release.Name }}-redis-master + redis_port: 6379 application-override.yaml: | {{- toYaml (index .Values "application-override.yaml") | nindent 4 }} diff --git a/infra/charts/feast/charts/feast-serving/values.yaml b/infra/charts/feast/charts/feast-serving/values.yaml index 8ddc27aa573..4ff6cc3a130 100644 --- a/infra/charts/feast/charts/feast-serving/values.yaml +++ b/infra/charts/feast/charts/feast-serving/values.yaml @@ -5,17 +5,14 @@ image: # image.repository -- Docker image repository repository: gcr.io/kf-feast/feast-serving # image.tag -- Image tag - tag: 0.4.7 + tag: dev # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent -# "store.yaml" -- Store [config](https://github.com/gojek/feast/blob/master/protos/feast/core/Store.proto#L32) in yaml format. This is an [example](https://github.com/gojek/feast/blob/v0.4-branch/serving/sample_redis_config.yml) for Redis -store.yaml: {} - -# "application-override.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` +# "application-override.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` application-override.yaml: {} -# "application-secret.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/v0.4-branch/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml` +# "application-secret.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify managing the config application-secret.yaml: {} gcpServiceAccount: diff --git a/infra/charts/feast/charts/prometheus/values.yaml b/infra/charts/feast/charts/prometheus/values.yaml index 3fee953d963..d159a31d128 100644 --- a/infra/charts/feast/charts/prometheus/values.yaml +++ b/infra/charts/feast/charts/prometheus/values.yaml @@ -26,7 +26,7 @@ serviceAccounts: alertmanager: ## If false, alertmanager will not be installed ## - enabled: true + enabled: false ## alertmanager container name ## @@ -894,7 +894,7 @@ server: pushgateway: ## If false, pushgateway will not be installed ## - enabled: true + enabled: false ## Use an alternate scheduler, e.g. "stork". ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index 116acbd4543..48fcaf09ee6 100644 --- a/infra/charts/feast/requirements.yaml +++ b/infra/charts/feast/requirements.yaml @@ -1,14 +1,14 @@ dependencies: - name: feast-core - version: 0.4.6 + version: 0.5.0-alpha.1 condition: feast-core.enabled - name: feast-serving alias: feast-online-serving - version: 0.4.6 + version: 0.5.0-alpha.1 condition: feast-online-serving.enabled - name: feast-serving alias: feast-batch-serving - version: 0.4.6 + version: 0.5.0-alpha.1 condition: feast-batch-serving.enabled - name: postgresql version: 8.6.1 diff --git a/infra/charts/feast/templates/tests/test-feast-online-serving.yaml b/infra/charts/feast/templates/tests/test-feast-online-serving.yaml index f9a213aabb8..8823e3004f6 100644 --- a/infra/charts/feast/templates/tests/test-feast-online-serving.yaml +++ b/infra/charts/feast/templates/tests/test-feast-online-serving.yaml @@ -15,7 +15,7 @@ spec: - bash - -c - | - pip install -U feast==0.4.* + pip install feast -U feast==0.4.* cat < featureset.yaml kind: feature_set From 718f45f512c076b9bb7f4688bfa3aa4ba5be5fcc Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Wed, 29 Apr 2020 16:23:50 +0800 Subject: [PATCH 10/15] Typo --- .../charts/feast/templates/tests/test-feast-online-serving.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/charts/feast/templates/tests/test-feast-online-serving.yaml b/infra/charts/feast/templates/tests/test-feast-online-serving.yaml index 8823e3004f6..f9a213aabb8 100644 --- a/infra/charts/feast/templates/tests/test-feast-online-serving.yaml +++ b/infra/charts/feast/templates/tests/test-feast-online-serving.yaml @@ -15,7 +15,7 @@ spec: - bash - -c - | - pip install feast -U feast==0.4.* + pip install -U feast==0.4.* cat < featureset.yaml kind: feature_set From 5291a499e0836aa32eed9ed0fcdb6e8db4d5dd7b Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Thu, 30 Apr 2020 15:01:08 +0800 Subject: [PATCH 11/15] Add 4 different application config with flag toggle for Feast Core and Serving - application.yaml: default application.yaml bundled in the jar - application-generated.yaml: additional config generated by Helm that is valid when the dependencies like Postgres, Kafka and Redis are installed with default config - application-secret.yaml: config to override default and Helm generated config - application-override.yaml: same as application-secret.yaml but config is created as ConfigMap vs Secret and has a higher precendence than application-secret.yaml --- infra/charts/feast/README.md | 2 +- infra/charts/feast/README.md.gotmpl | 2 +- infra/charts/feast/charts/feast-core/README.md | 6 ++++-- .../charts/feast-core/templates/configmap.yaml | 11 +++++------ .../feast-core/templates/deployment.yaml | 14 +++++++++++++- .../charts/feast/charts/feast-core/values.yaml | 18 ++++++++++++++---- .../feast/charts/feast-serving/README.md | 6 ++++-- .../feast-serving/templates/configmap.yaml | 6 +++++- .../feast-serving/templates/deployment.yaml | 14 +++++++++++++- .../feast/charts/feast-serving/values.yaml | 18 ++++++++++++++---- 10 files changed, 74 insertions(+), 23 deletions(-) diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index f3ed9a062bd..112bc725ad1 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -10,7 +10,7 @@ Feature store for machine learning. Current chart version is `0.5.0-alpha.1` helm repo add feast-charts https://feast-charts.storage.googleapis.com helm repo update -# Create secret for Feast database, replace accordingly +# Create secret for Feast database, replace with the desired value kubectl create secret generic feast-postgresql \ --from-literal=postgresql-password= diff --git a/infra/charts/feast/README.md.gotmpl b/infra/charts/feast/README.md.gotmpl index ed018e6f814..51cf2652e04 100644 --- a/infra/charts/feast/README.md.gotmpl +++ b/infra/charts/feast/README.md.gotmpl @@ -9,7 +9,7 @@ helm repo add feast-charts https://feast-charts.storage.googleapis.com helm repo update -# Create secret for Feast database, replace accordingly +# Create secret for Feast database, replace with the desired value kubectl create secret generic feast-postgresql \ --from-literal=postgresql-password= diff --git a/infra/charts/feast/charts/feast-core/README.md b/infra/charts/feast/charts/feast-core/README.md index a3daea8c7ff..e8b3126bf04 100644 --- a/infra/charts/feast/charts/feast-core/README.md +++ b/infra/charts/feast/charts/feast-core/README.md @@ -12,8 +12,10 @@ Current chart version is `0.5.0-alpha.1` | Key | Type | Default | Description | |-----|------|---------|-------------| -| "application-override.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | -| "application-secret.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify managing the config | +| "application-generated.yaml".enabled | bool | `true` | Flag to include Helm generated configuration for Feast database URL, Kafka bootstrap servers and jobs metrics host. This is useful for deployment that uses default configuration for Kafka, Postgres and StatsD exporter. Please set `application-override.yaml` to override this configuration. | +| "application-override.yaml" | object | `{"enabled":true}` | Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | +| "application-secret.yaml" | object | `{"enabled":true}` | Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify config management. | +| "application.yaml".enabled | bool | `true` | Flag to include the default [configuration](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Please set `application-override.yaml` to override this configuration. | | envOverrides | object | `{}` | Extra environment variables to set | | gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | | gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | diff --git a/infra/charts/feast/charts/feast-core/templates/configmap.yaml b/infra/charts/feast/charts/feast-core/templates/configmap.yaml index 2bcaa8c8b37..bce32ef33a6 100644 --- a/infra/charts/feast/charts/feast-core/templates/configmap.yaml +++ b/infra/charts/feast/charts/feast-core/templates/configmap.yaml @@ -10,27 +10,26 @@ metadata: release: {{ .Release.Name }} heritage: {{ .Release.Service }} data: - application-default-postgresql.yaml: | + application-generated.yaml: | +{{- if index .Values "application-generated.yaml" "enabled" }} spring: datasource: url: jdbc:postgresql://{{ .Release.Name }}-postgresql:5432/postgres - - application-default-kafka.yaml: | feast: stream: type: kafka options: bootstrapServers: {{ .Release.Name }}-kafka:9092 topic: feast - - application-default-statsd.yaml: | - feast: jobs: metrics: enabled: true type: statsd host: {{ .Release.Name }}-prometheus-statsd-exporter-udp port: 9125 +{{- end }} application-override.yaml: | +{{- if index .Values "application-override.yaml" "enabled" }} {{- toYaml (index .Values "application-override.yaml") | nindent 4 }} +{{- end }} \ No newline at end of file diff --git a/infra/charts/feast/charts/feast-core/templates/deployment.yaml b/infra/charts/feast/charts/feast-core/templates/deployment.yaml index 9e3ce058d39..e7692d4dba0 100644 --- a/infra/charts/feast/charts/feast-core/templates/deployment.yaml +++ b/infra/charts/feast/charts/feast-core/templates/deployment.yaml @@ -102,7 +102,19 @@ spec: - java - -jar - /opt/feast/feast-core.jar - - --spring.config.additional-location=/etc/feast/application-default-postgresql.yaml,/etc/feast/application-default-kafka.yaml,/etc/feast/application-default-statsd.yaml,/etc/secrets/feast/application-secret.yaml,/etc/feast/application-override.yaml + - --spring.config.location= + {{- if index .Values "application.yaml" "enabled" -}} + classpath:/application.yml + {{- end }} + {{- if index .Values "application-generated.yaml" "enabled" -}} + ,file:/etc/feast/application-generated.yaml + {{- end }} + {{- if index .Values "application-secret.yaml" "enabled" -}} + ,file:/etc/secrets/feast/application-secret.yaml + {{- end }} + {{- if index .Values "application-override.yaml" "enabled" -}} + ,file:/etc/feast/application-override.yaml + {{- end }} ports: - name: http containerPort: {{ .Values.service.http.targetPort }} diff --git a/infra/charts/feast/charts/feast-core/values.yaml b/infra/charts/feast/charts/feast-core/values.yaml index 61f5c89e486..cbcc10886d7 100644 --- a/infra/charts/feast/charts/feast-core/values.yaml +++ b/infra/charts/feast/charts/feast-core/values.yaml @@ -9,11 +9,21 @@ image: # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent -# "application-override.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` -application-override.yaml: {} +application.yaml: + # "application.yaml".enabled -- Flag to include the default [configuration](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Please set `application-override.yaml` to override this configuration. + enabled: true + +application-generated.yaml: + # "application-generated.yaml".enabled -- Flag to include Helm generated configuration for Feast database URL, Kafka bootstrap servers and jobs metrics host. This is useful for deployment that uses default configuration for Kafka, Postgres and StatsD exporter. Please set `application-override.yaml` to override this configuration. + enabled: true -# "application-secret.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify managing the config -application-secret.yaml: {} +# "application-secret.yaml" -- Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify config management. +application-secret.yaml: + enabled: true + +# "application-override.yaml" -- Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` +application-override.yaml: + enabled: true gcpServiceAccount: # gcpServiceAccount.enabled -- Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key diff --git a/infra/charts/feast/charts/feast-serving/README.md b/infra/charts/feast/charts/feast-serving/README.md index e5b9d217446..df64b56aa42 100644 --- a/infra/charts/feast/charts/feast-serving/README.md +++ b/infra/charts/feast/charts/feast-serving/README.md @@ -12,8 +12,10 @@ Current chart version is `0.5.0-alpha.1` | Key | Type | Default | Description | |-----|------|---------|-------------| -| "application-override.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | -| "application-secret.yaml" | object | `{}` | Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify managing the config | +| "application-generated.yaml".enabled | bool | `true` | Flag to include Helm generated configuration for Feast Core host, Redis store and job store. This is useful for deployment that uses default configuration for Redis. Please set `application-override.yaml` to override this configuration. | +| "application-override.yaml" | object | `{"enabled":true}` | Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` | +| "application-secret.yaml" | object | `{"enabled":true}` | Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify config management. | +| "application.yaml".enabled | bool | `true` | Flag to include the default [configuration](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Please set `application-override.yaml` to override this configuration. | | envOverrides | object | `{}` | Extra environment variables to set | | gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | | gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | diff --git a/infra/charts/feast/charts/feast-serving/templates/configmap.yaml b/infra/charts/feast/charts/feast-serving/templates/configmap.yaml index d03f68a3b9b..7c895ce530b 100644 --- a/infra/charts/feast/charts/feast-serving/templates/configmap.yaml +++ b/infra/charts/feast/charts/feast-serving/templates/configmap.yaml @@ -10,7 +10,8 @@ metadata: release: {{ .Release.Name }} heritage: {{ .Release.Service }} data: - application-default.yaml: | + application-generated.yaml: | +{{- if index .Values "application-generated.yaml" "enabled" }} feast: core-host: {{ .Release.Name }}-feast-core @@ -28,6 +29,9 @@ data: job_store: redis_host: {{ .Release.Name }}-redis-master redis_port: 6379 +{{- end }} application-override.yaml: | +{{- if index .Values "application-override.yaml" "enabled" }} {{- toYaml (index .Values "application-override.yaml") | nindent 4 }} +{{- end }} diff --git a/infra/charts/feast/charts/feast-serving/templates/deployment.yaml b/infra/charts/feast/charts/feast-serving/templates/deployment.yaml index db8348bd722..fc283c03e18 100644 --- a/infra/charts/feast/charts/feast-serving/templates/deployment.yaml +++ b/infra/charts/feast/charts/feast-serving/templates/deployment.yaml @@ -94,7 +94,19 @@ spec: - java - -jar - /opt/feast/feast-serving.jar - - --spring.config.additional-location=/etc/feast/application-default.yaml,/etc/feast/application-override.yaml + - --spring.config.location= + {{- if index .Values "application.yaml" "enabled" -}} + classpath:/application.yml + {{- end }} + {{- if index .Values "application-generated.yaml" "enabled" -}} + ,file:/etc/feast/application-generated.yaml + {{- end }} + {{- if index .Values "application-secret.yaml" "enabled" -}} + ,file:/etc/secrets/feast/application-secret.yaml + {{- end }} + {{- if index .Values "application-override.yaml" "enabled" -}} + ,file:/etc/feast/application-override.yaml + {{- end }} ports: - name: http diff --git a/infra/charts/feast/charts/feast-serving/values.yaml b/infra/charts/feast/charts/feast-serving/values.yaml index 4ff6cc3a130..1eb0fcb1fa7 100644 --- a/infra/charts/feast/charts/feast-serving/values.yaml +++ b/infra/charts/feast/charts/feast-serving/values.yaml @@ -9,11 +9,21 @@ image: # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent -# "application-override.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` -application-override.yaml: {} +application.yaml: + # "application.yaml".enabled -- Flag to include the default [configuration](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Please set `application-override.yaml` to override this configuration. + enabled: true + +application-generated.yaml: + # "application-generated.yaml".enabled -- Flag to include Helm generated configuration for Feast Core host, Redis store and job store. This is useful for deployment that uses default configuration for Redis. Please set `application-override.yaml` to override this configuration. + enabled: true -# "application-secret.yaml" -- Configuration to override default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify managing the config -application-secret.yaml: {} +# "application-secret.yaml" -- Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify config management. +application-secret.yaml: + enabled: true + +# "application-override.yaml" -- Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a ConfigMap. `application-override.yaml` has a higher precedence than `application-secret.yaml` +application-override.yaml: + enabled: true gcpServiceAccount: # gcpServiceAccount.enabled -- Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key From 45a271c947e7affd5e434cb13bfe0d1a030fa9a3 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Thu, 30 Apr 2020 15:46:06 +0800 Subject: [PATCH 12/15] Update apiVersion for deployment in prometheus-statsd-exporter so it works with latest Kubernetes version --- .../charts/prometheus-statsd-exporter/templates/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/charts/feast/charts/prometheus-statsd-exporter/templates/deployment.yaml b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/deployment.yaml index 2c36756ca47..44fac913b6a 100644 --- a/infra/charts/feast/charts/prometheus-statsd-exporter/templates/deployment.yaml +++ b/infra/charts/feast/charts/prometheus-statsd-exporter/templates/deployment.yaml @@ -1,4 +1,4 @@ -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: name: {{ template "prometheus-statsd-exporter.fullname" . }} From 3d50664df8715eb138b4ce1672f57d1b157d9f31 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Thu, 30 Apr 2020 23:58:58 +0800 Subject: [PATCH 13/15] Cleanup unsued template function and add checksum to configmap and secret So that deployment will be updated when configmap and secret are updated --- infra/charts/feast/charts/feast-core/README.md | 2 +- .../feast/charts/feast-core/templates/deployment.yaml | 6 ++++-- infra/charts/feast/charts/feast-core/values.yaml | 2 +- .../feast/charts/feast-serving/templates/_helpers.tpl | 7 ------- .../feast/charts/feast-serving/templates/deployment.yaml | 4 +++- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/infra/charts/feast/charts/feast-core/README.md b/infra/charts/feast/charts/feast-core/README.md index e8b3126bf04..7c033090b9c 100644 --- a/infra/charts/feast/charts/feast-core/README.md +++ b/infra/charts/feast/charts/feast-core/README.md @@ -50,7 +50,7 @@ Current chart version is `0.5.0-alpha.1` | logLevel | string | `"WARN"` | Default log level, use either one of `DEBUG`, `INFO`, `WARN` or `ERROR` | | logType | string | `"Console"` | Log format, either `JSON` or `Console` | | nodeSelector | object | `{}` | Node labels for pod assignment | -| postgresql.existingSecret | string | `nil` | Existing secret to use for authenticating to Postgres | +| postgresql.existingSecret | string | `""` | Existing secret to use for authenticating to Postgres | | prometheus.enabled | bool | `true` | Flag to enable scraping of Feast Core metrics | | readinessProbe.enabled | bool | `true` | Flag to enabled the probe | | readinessProbe.failureThreshold | int | `5` | Min consecutive failures for the probe to be considered failed | diff --git a/infra/charts/feast/charts/feast-core/templates/deployment.yaml b/infra/charts/feast/charts/feast-core/templates/deployment.yaml index e7692d4dba0..1f4fd996efa 100644 --- a/infra/charts/feast/charts/feast-core/templates/deployment.yaml +++ b/infra/charts/feast/charts/feast-core/templates/deployment.yaml @@ -18,10 +18,12 @@ spec: release: {{ .Release.Name }} template: metadata: - {{- if .Values.prometheus.enabled }} annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- if .Values.prometheus.enabled }} prometheus.io/path: /metrics - prometheus.io/port: "8080" + prometheus.io/port: "{{ .Values.service.http.targetPort }}" prometheus.io/scrape: "true" {{- end }} labels: diff --git a/infra/charts/feast/charts/feast-core/values.yaml b/infra/charts/feast/charts/feast-core/values.yaml index cbcc10886d7..28b5a952d54 100644 --- a/infra/charts/feast/charts/feast-core/values.yaml +++ b/infra/charts/feast/charts/feast-core/values.yaml @@ -36,7 +36,7 @@ gcpServiceAccount: postgresql: # postgresql.existingSecret -- Existing secret to use for authenticating to Postgres - existingSecret: + existingSecret: "" # javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). For better performance, it is advised to set the min and max heap:
`-Xms2048m -Xmx2048m` javaOpts: diff --git a/infra/charts/feast/charts/feast-serving/templates/_helpers.tpl b/infra/charts/feast/charts/feast-serving/templates/_helpers.tpl index ab670cc8cc7..49abb6b8e50 100644 --- a/infra/charts/feast/charts/feast-serving/templates/_helpers.tpl +++ b/infra/charts/feast/charts/feast-serving/templates/_helpers.tpl @@ -43,10 +43,3 @@ app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} - -{{/* -Helpers -*/}} -{{- define "bq_store_and_no_job_options" -}} -{{ and (eq (index .Values "store.yaml" "type") "BIGQUERY") (empty (index .Values "application.yaml" "feast" "jobs" "store-options")) }} -{{- end -}} diff --git a/infra/charts/feast/charts/feast-serving/templates/deployment.yaml b/infra/charts/feast/charts/feast-serving/templates/deployment.yaml index fc283c03e18..bb8fdc55ae5 100644 --- a/infra/charts/feast/charts/feast-serving/templates/deployment.yaml +++ b/infra/charts/feast/charts/feast-serving/templates/deployment.yaml @@ -19,9 +19,11 @@ spec: template: metadata: annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} {{- if .Values.prometheus.enabled }} prometheus.io/path: /metrics - prometheus.io/port: "8080" + prometheus.io/port: "{{ .Values.service.http.targetPort }}" prometheus.io/scrape: "true" {{- end }} labels: From 72e6144fa79d5792089e1a937ec174f50f2ee7d8 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Sat, 2 May 2020 15:29:57 +0800 Subject: [PATCH 14/15] Remove 3rd party charts from charts folder --- infra/charts/feast/README.md | 29 +- infra/charts/feast/README.md.gotmpl | 17 +- infra/charts/feast/charts/grafana-5.0.5.tgz | Bin 0 -> 19271 bytes infra/charts/feast/charts/grafana/.helmignore | 23 - infra/charts/feast/charts/grafana/Chart.yaml | 19 - infra/charts/feast/charts/grafana/README.md | 321 ---- .../charts/grafana/ci/default-values.yaml | 1 - .../ci/with-dashboard-json-values.yaml | 53 - .../grafana/ci/with-dashboard-values.yaml | 19 - .../grafana/dashboards/custom-dashboard.json | 1 - .../feast/charts/grafana/templates/NOTES.txt | 53 - .../charts/grafana/templates/_helpers.tpl | 82 - .../feast/charts/grafana/templates/_pod.tpl | 369 ---- .../charts/grafana/templates/clusterrole.yaml | 25 - .../grafana/templates/clusterrolebinding.yaml | 20 - .../configmap-dashboard-provider.yaml | 25 - .../charts/grafana/templates/configmap.yaml | 69 - .../templates/dashboards-json-configmap.yaml | 35 - .../charts/grafana/templates/deployment.yaml | 44 - .../grafana/templates/headless-service.yaml | 18 - .../charts/grafana/templates/ingress.yaml | 42 - .../templates/poddisruptionbudget.yaml | 22 - .../grafana/templates/podsecuritypolicy.yaml | 52 - .../feast/charts/grafana/templates/pvc.yaml | 28 - .../feast/charts/grafana/templates/role.yaml | 32 - .../charts/grafana/templates/rolebinding.yaml | 27 - .../charts/grafana/templates/secret-env.yaml | 14 - .../charts/grafana/templates/secret.yaml | 20 - .../charts/grafana/templates/service.yaml | 46 - .../grafana/templates/serviceaccount.yaml | 13 - .../charts/grafana/templates/statefulset.yaml | 44 - .../templates/tests/test-configmap.yaml | 17 - .../tests/test-podsecuritypolicy.yaml | 29 - .../grafana/templates/tests/test-role.yaml | 14 - .../templates/tests/test-rolebinding.yaml | 17 - .../templates/tests/test-serviceaccount.yaml | 9 - .../charts/grafana/templates/tests/test.yaml | 47 - infra/charts/feast/charts/grafana/values.yaml | 485 ------ infra/charts/feast/charts/kafka-0.20.8.tgz | Bin 0 -> 31688 bytes infra/charts/feast/charts/kafka/.helmignore | 21 - infra/charts/feast/charts/kafka/Chart.yaml | 24 - infra/charts/feast/charts/kafka/README.md | 432 ----- .../charts/kafka/charts/zookeeper-2.1.0.tgz | Bin 10646 -> 0 bytes .../feast/charts/kafka/requirements.lock | 6 - .../feast/charts/kafka/requirements.yaml | 5 - .../feast/charts/kafka/templates/NOTES.txt | 76 - .../feast/charts/kafka/templates/_helpers.tpl | 128 -- .../kafka/templates/configmap-config.yaml | 58 - .../charts/kafka/templates/configmap-jmx.yaml | 64 - .../templates/deployment-kafka-exporter.yaml | 45 - .../charts/kafka/templates/job-config.yaml | 29 - .../kafka/templates/podisruptionbudget.yaml | 14 - .../kafka/templates/prometheusrules.yaml | 16 - .../templates/service-brokers-external.yaml | 74 - .../kafka/templates/service-brokers.yaml | 36 - .../kafka/templates/service-headless.yaml | 21 - .../kafka/templates/servicemonitors.yaml | 47 - .../charts/kafka/templates/statefulset.yaml | 272 --- .../test_topic_create_consume_produce.yaml | 24 - infra/charts/feast/charts/kafka/values.yaml | 503 ------ .../charts/feast/charts/postgresql-8.6.1.tgz | Bin 0 -> 31082 bytes .../feast/charts/postgresql/.helmignore | 2 - .../charts/feast/charts/postgresql/Chart.yaml | 22 - .../charts/feast/charts/postgresql/README.md | 566 ------ .../charts/postgresql/ci/default-values.yaml | 1 - .../ci/shmvolume-disabled-values.yaml | 2 - .../feast/charts/postgresql/files/README.md | 1 - .../charts/postgresql/files/conf.d/README.md | 4 - .../docker-entrypoint-initdb.d/README.md | 3 - .../charts/postgresql/templates/NOTES.txt | 60 - .../charts/postgresql/templates/_helpers.tpl | 420 ----- .../postgresql/templates/configmap.yaml | 26 - .../templates/extended-config-configmap.yaml | 21 - .../templates/initialization-configmap.yaml | 24 - .../templates/metrics-configmap.yaml | 13 - .../postgresql/templates/metrics-svc.yaml | 26 - .../postgresql/templates/networkpolicy.yaml | 38 - .../postgresql/templates/prometheusrule.yaml | 23 - .../charts/postgresql/templates/secrets.yaml | 23 - .../postgresql/templates/serviceaccount.yaml | 11 - .../postgresql/templates/servicemonitor.yaml | 33 - .../templates/statefulset-slaves.yaml | 299 ---- .../postgresql/templates/statefulset.yaml | 458 ----- .../postgresql/templates/svc-headless.yaml | 19 - .../charts/postgresql/templates/svc-read.yaml | 31 - .../charts/postgresql/templates/svc.yaml | 38 - .../charts/postgresql/values-production.yaml | 520 ------ .../charts/postgresql/values.schema.json | 103 -- .../feast/charts/postgresql/values.yaml | 526 ------ .../charts/feast/charts/prometheus-11.0.2.tgz | Bin 0 -> 32813 bytes .../feast/charts/prometheus/.helmignore | 23 - .../charts/feast/charts/prometheus/Chart.yaml | 20 - .../charts/feast/charts/prometheus/README.md | 471 ----- .../feast/charts/prometheus/requirements.yaml | 7 - .../charts/prometheus/templates/NOTES.txt | 112 -- .../charts/prometheus/templates/_helpers.tpl | 276 --- .../templates/alertmanager-clusterrole.yaml | 21 - .../alertmanager-clusterrolebinding.yaml | 16 - .../templates/alertmanager-configmap.yaml | 18 - .../templates/alertmanager-deployment.yaml | 142 -- .../templates/alertmanager-ingress.yaml | 42 - .../templates/alertmanager-networkpolicy.yaml | 19 - .../templates/alertmanager-pdb.yaml | 13 - .../alertmanager-podsecuritypolicy.yaml | 48 - .../templates/alertmanager-pvc.yaml | 32 - .../alertmanager-service-headless.yaml | 30 - .../templates/alertmanager-service.yaml | 52 - .../alertmanager-serviceaccount.yaml | 8 - .../templates/alertmanager-statefulset.yaml | 152 -- .../templates/node-exporter-daemonset.yaml | 116 -- .../node-exporter-podsecuritypolicy.yaml | 55 - .../templates/node-exporter-role.yaml | 17 - .../templates/node-exporter-rolebinding.yaml | 19 - .../templates/node-exporter-service.yaml | 40 - .../node-exporter-serviceaccount.yaml | 8 - .../templates/pushgateway-clusterrole.yaml | 21 - .../pushgateway-clusterrolebinding.yaml | 16 - .../templates/pushgateway-deployment.yaml | 100 -- .../templates/pushgateway-ingress.yaml | 39 - .../templates/pushgateway-networkpolicy.yaml | 19 - .../prometheus/templates/pushgateway-pdb.yaml | 13 - .../pushgateway-podsecuritypolicy.yaml | 44 - .../prometheus/templates/pushgateway-pvc.yaml | 30 - .../templates/pushgateway-service.yaml | 40 - .../templates/pushgateway-serviceaccount.yaml | 8 - .../templates/server-clusterrole.yaml | 47 - .../templates/server-clusterrolebinding.yaml | 16 - .../templates/server-configmap.yaml | 81 - .../templates/server-deployment.yaml | 217 --- .../prometheus/templates/server-ingress.yaml | 44 - .../templates/server-networkpolicy.yaml | 17 - .../prometheus/templates/server-pdb.yaml | 13 - .../templates/server-podsecuritypolicy.yaml | 53 - .../prometheus/templates/server-pvc.yaml | 34 - .../templates/server-service-headless.yaml | 26 - .../prometheus/templates/server-service.yaml | 59 - .../templates/server-serviceaccount.yaml | 10 - .../templates/server-statefulset.yaml | 222 --- .../prometheus/templates/server-vpa.yaml | 24 - .../feast/charts/prometheus/values.yaml | 1514 ----------------- infra/charts/feast/charts/redis-10.5.6.tgz | Bin 0 -> 31002 bytes infra/charts/feast/charts/redis/.helmignore | 3 - infra/charts/feast/charts/redis/Chart.yaml | 19 - infra/charts/feast/charts/redis/README.md | 497 ------ .../feast/charts/redis/ci/default-values.yaml | 1 - .../feast/charts/redis/ci/dev-values.yaml | 9 - .../charts/redis/ci/extra-flags-values.yaml | 11 - .../redis/ci/insecure-sentinel-values.yaml | 524 ------ .../redis/ci/production-sentinel-values.yaml | 524 ------ .../charts/redis/ci/production-values.yaml | 525 ------ .../charts/redis/ci/redis-lib-values.yaml | 13 - .../redis/ci/redisgraph-module-values.yaml | 10 - .../feast/charts/redis/templates/NOTES.txt | 104 -- .../feast/charts/redis/templates/_helpers.tpl | 355 ---- .../charts/redis/templates/configmap.yaml | 52 - .../charts/redis/templates/headless-svc.yaml | 24 - .../redis/templates/health-configmap.yaml | 134 -- .../redis/templates/metrics-prometheus.yaml | 30 - .../charts/redis/templates/metrics-svc.yaml | 30 - .../charts/redis/templates/networkpolicy.yaml | 73 - .../redis/templates/prometheusrule.yaml | 23 - .../feast/charts/redis/templates/psp.yaml | 42 - .../templates/redis-master-statefulset.yaml | 419 ----- .../redis/templates/redis-master-svc.yaml | 39 - .../charts/redis/templates/redis-role.yaml | 21 - .../redis/templates/redis-rolebinding.yaml | 18 - .../redis/templates/redis-serviceaccount.yaml | 11 - .../templates/redis-slave-statefulset.yaml | 437 ----- .../redis/templates/redis-slave-svc.yaml | 40 - .../templates/redis-with-sentinel-svc.yaml | 40 - .../feast/charts/redis/templates/secret.yaml | 14 - .../feast/charts/redis/values-production.yaml | 630 ------- .../feast/charts/redis/values.schema.json | 168 -- infra/charts/feast/charts/redis/values.yaml | 631 ------- infra/charts/feast/requirements.lock | 30 + infra/charts/feast/requirements.yaml | 5 + 176 files changed, 49 insertions(+), 17310 deletions(-) create mode 100644 infra/charts/feast/charts/grafana-5.0.5.tgz delete mode 100644 infra/charts/feast/charts/grafana/.helmignore delete mode 100644 infra/charts/feast/charts/grafana/Chart.yaml delete mode 100644 infra/charts/feast/charts/grafana/README.md delete mode 100644 infra/charts/feast/charts/grafana/ci/default-values.yaml delete mode 100644 infra/charts/feast/charts/grafana/ci/with-dashboard-json-values.yaml delete mode 100644 infra/charts/feast/charts/grafana/ci/with-dashboard-values.yaml delete mode 100644 infra/charts/feast/charts/grafana/dashboards/custom-dashboard.json delete mode 100644 infra/charts/feast/charts/grafana/templates/NOTES.txt delete mode 100644 infra/charts/feast/charts/grafana/templates/_helpers.tpl delete mode 100644 infra/charts/feast/charts/grafana/templates/_pod.tpl delete mode 100644 infra/charts/feast/charts/grafana/templates/clusterrole.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/clusterrolebinding.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/configmap-dashboard-provider.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/configmap.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/dashboards-json-configmap.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/deployment.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/headless-service.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/ingress.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/poddisruptionbudget.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/podsecuritypolicy.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/pvc.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/role.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/rolebinding.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/secret-env.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/secret.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/service.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/serviceaccount.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/statefulset.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-configmap.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-podsecuritypolicy.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-role.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-rolebinding.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/tests/test-serviceaccount.yaml delete mode 100644 infra/charts/feast/charts/grafana/templates/tests/test.yaml delete mode 100644 infra/charts/feast/charts/grafana/values.yaml create mode 100644 infra/charts/feast/charts/kafka-0.20.8.tgz delete mode 100644 infra/charts/feast/charts/kafka/.helmignore delete mode 100755 infra/charts/feast/charts/kafka/Chart.yaml delete mode 100644 infra/charts/feast/charts/kafka/README.md delete mode 100644 infra/charts/feast/charts/kafka/charts/zookeeper-2.1.0.tgz delete mode 100644 infra/charts/feast/charts/kafka/requirements.lock delete mode 100644 infra/charts/feast/charts/kafka/requirements.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/NOTES.txt delete mode 100644 infra/charts/feast/charts/kafka/templates/_helpers.tpl delete mode 100644 infra/charts/feast/charts/kafka/templates/configmap-config.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/configmap-jmx.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/deployment-kafka-exporter.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/job-config.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/podisruptionbudget.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/prometheusrules.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/service-brokers-external.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/service-brokers.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/service-headless.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/servicemonitors.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/statefulset.yaml delete mode 100644 infra/charts/feast/charts/kafka/templates/tests/test_topic_create_consume_produce.yaml delete mode 100644 infra/charts/feast/charts/kafka/values.yaml create mode 100644 infra/charts/feast/charts/postgresql-8.6.1.tgz delete mode 100644 infra/charts/feast/charts/postgresql/.helmignore delete mode 100644 infra/charts/feast/charts/postgresql/Chart.yaml delete mode 100644 infra/charts/feast/charts/postgresql/README.md delete mode 100644 infra/charts/feast/charts/postgresql/ci/default-values.yaml delete mode 100644 infra/charts/feast/charts/postgresql/ci/shmvolume-disabled-values.yaml delete mode 100644 infra/charts/feast/charts/postgresql/files/README.md delete mode 100644 infra/charts/feast/charts/postgresql/files/conf.d/README.md delete mode 100644 infra/charts/feast/charts/postgresql/files/docker-entrypoint-initdb.d/README.md delete mode 100644 infra/charts/feast/charts/postgresql/templates/NOTES.txt delete mode 100644 infra/charts/feast/charts/postgresql/templates/_helpers.tpl delete mode 100644 infra/charts/feast/charts/postgresql/templates/configmap.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/extended-config-configmap.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/initialization-configmap.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/metrics-configmap.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/metrics-svc.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/networkpolicy.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/prometheusrule.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/secrets.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/serviceaccount.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/servicemonitor.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/statefulset-slaves.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/statefulset.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/svc-headless.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/svc-read.yaml delete mode 100644 infra/charts/feast/charts/postgresql/templates/svc.yaml delete mode 100644 infra/charts/feast/charts/postgresql/values-production.yaml delete mode 100644 infra/charts/feast/charts/postgresql/values.schema.json delete mode 100644 infra/charts/feast/charts/postgresql/values.yaml create mode 100644 infra/charts/feast/charts/prometheus-11.0.2.tgz delete mode 100644 infra/charts/feast/charts/prometheus/.helmignore delete mode 100644 infra/charts/feast/charts/prometheus/Chart.yaml delete mode 100644 infra/charts/feast/charts/prometheus/README.md delete mode 100644 infra/charts/feast/charts/prometheus/requirements.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/NOTES.txt delete mode 100644 infra/charts/feast/charts/prometheus/templates/_helpers.tpl delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrole.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrolebinding.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-configmap.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-deployment.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-ingress.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-networkpolicy.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-pdb.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-podsecuritypolicy.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-pvc.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-service-headless.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-service.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-serviceaccount.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/alertmanager-statefulset.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-daemonset.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-podsecuritypolicy.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-role.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-rolebinding.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-service.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/node-exporter-serviceaccount.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrole.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrolebinding.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-deployment.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-ingress.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-networkpolicy.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-pdb.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-podsecuritypolicy.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-pvc.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-service.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/pushgateway-serviceaccount.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-clusterrole.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-clusterrolebinding.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-configmap.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-deployment.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-ingress.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-networkpolicy.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-pdb.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-podsecuritypolicy.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-pvc.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-service-headless.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-service.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-serviceaccount.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-statefulset.yaml delete mode 100644 infra/charts/feast/charts/prometheus/templates/server-vpa.yaml delete mode 100644 infra/charts/feast/charts/prometheus/values.yaml create mode 100644 infra/charts/feast/charts/redis-10.5.6.tgz delete mode 100644 infra/charts/feast/charts/redis/.helmignore delete mode 100644 infra/charts/feast/charts/redis/Chart.yaml delete mode 100644 infra/charts/feast/charts/redis/README.md delete mode 100644 infra/charts/feast/charts/redis/ci/default-values.yaml delete mode 100644 infra/charts/feast/charts/redis/ci/dev-values.yaml delete mode 100644 infra/charts/feast/charts/redis/ci/extra-flags-values.yaml delete mode 100644 infra/charts/feast/charts/redis/ci/insecure-sentinel-values.yaml delete mode 100644 infra/charts/feast/charts/redis/ci/production-sentinel-values.yaml delete mode 100644 infra/charts/feast/charts/redis/ci/production-values.yaml delete mode 100644 infra/charts/feast/charts/redis/ci/redis-lib-values.yaml delete mode 100644 infra/charts/feast/charts/redis/ci/redisgraph-module-values.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/NOTES.txt delete mode 100644 infra/charts/feast/charts/redis/templates/_helpers.tpl delete mode 100644 infra/charts/feast/charts/redis/templates/configmap.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/headless-svc.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/health-configmap.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/metrics-prometheus.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/metrics-svc.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/networkpolicy.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/prometheusrule.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/psp.yaml delete mode 100755 infra/charts/feast/charts/redis/templates/redis-master-statefulset.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/redis-master-svc.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/redis-role.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/redis-rolebinding.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/redis-serviceaccount.yaml delete mode 100755 infra/charts/feast/charts/redis/templates/redis-slave-statefulset.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/redis-slave-svc.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/redis-with-sentinel-svc.yaml delete mode 100644 infra/charts/feast/charts/redis/templates/secret.yaml delete mode 100644 infra/charts/feast/charts/redis/values-production.yaml delete mode 100644 infra/charts/feast/charts/redis/values.schema.json delete mode 100644 infra/charts/feast/charts/redis/values.yaml create mode 100644 infra/charts/feast/requirements.lock diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 112bc725ad1..3d868b2fd13 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -28,22 +28,19 @@ This chart install Feast deployment on a Kubernetes cluster using the [Helm](htt - Helm 2.15+ (not tested with Helm 3) - Persistent Volume support on the underlying infrastructure -## Chart requirements - -The chart dependencies are bundled in this chart so Feast users can use them directly. -It also allows Feast chart maintainers to set reasonable defaults values for the -dependencies so end users are not overwhelmed with the available configuration. - -| Name | Version | -|------|---------| -| [Feast Core](./charts/feast-core/README.md) | 0.5.0-alpha.1 | -| [Feast Serving](./charts/feast-serving/README.md) | 0.5.0-alpha.1 | -| [Postgresql](./charts/postgresql/README.md) | 8.6.1 | -| [Kafka](./charts/kafka/README.md) | 0.20.8 | -| [Redis](./charts/redis/README.md) | 10.5.6 | -| [Prometheus Statsd Exporter](./charts/prometheus-statsd-exporter/README.md) | 0.1.2 | -| [Prometheus](./charts/prometheus/README.md) | 11.0.2 | -| [Grafana](./charts/grafana/README.md) | 5.0.5 | +## Chart Requirements + +| Repository | Name | Version | +|------------|------|---------| +| | feast-core | 0.5.0-alpha.1 | +| | feast-serving | 0.5.0-alpha.1 | +| | feast-serving | 0.5.0-alpha.1 | +| | prometheus-statsd-exporter | 0.1.2 | +| https://kubernetes-charts-incubator.storage.googleapis.com/ | kafka | 0.20.8 | +| https://kubernetes-charts.storage.googleapis.com/ | grafana | 5.0.5 | +| https://kubernetes-charts.storage.googleapis.com/ | postgresql | 8.6.1 | +| https://kubernetes-charts.storage.googleapis.com/ | prometheus | 11.0.2 | +| https://kubernetes-charts.storage.googleapis.com/ | redis | 10.5.6 | ## Chart Values diff --git a/infra/charts/feast/README.md.gotmpl b/infra/charts/feast/README.md.gotmpl index 51cf2652e04..69d40fbb25e 100644 --- a/infra/charts/feast/README.md.gotmpl +++ b/infra/charts/feast/README.md.gotmpl @@ -27,22 +27,7 @@ This chart install Feast deployment on a Kubernetes cluster using the [Helm](htt - Helm 2.15+ (not tested with Helm 3) - Persistent Volume support on the underlying infrastructure -## Chart requirements - -The chart dependencies are bundled in this chart so Feast users can use them directly. -It also allows Feast chart maintainers to set reasonable defaults values for the -dependencies so end users are not overwhelmed with the available configuration. - -| Name | Version | -|------|---------| -| [Feast Core](./charts/feast-core/README.md) | 0.5.0-alpha.1 | -| [Feast Serving](./charts/feast-serving/README.md) | 0.5.0-alpha.1 | -| [Postgresql](./charts/postgresql/README.md) | 8.6.1 | -| [Kafka](./charts/kafka/README.md) | 0.20.8 | -| [Redis](./charts/redis/README.md) | 10.5.6 | -| [Prometheus Statsd Exporter](./charts/prometheus-statsd-exporter/README.md) | 0.1.2 | -| [Prometheus](./charts/prometheus/README.md) | 11.0.2 | -| [Grafana](./charts/grafana/README.md) | 5.0.5 | +{{ template "chart.requirementsSection" . }} {{ template "chart.valuesSection" . }} diff --git a/infra/charts/feast/charts/grafana-5.0.5.tgz b/infra/charts/feast/charts/grafana-5.0.5.tgz new file mode 100644 index 0000000000000000000000000000000000000000..06eb83a5e58e424198c76d93dd3c929346b94609 GIT binary patch literal 19271 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 z�0Xod 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 literal 0 HcmV?d00001 diff --git a/infra/charts/feast/charts/grafana/.helmignore b/infra/charts/feast/charts/grafana/.helmignore deleted file mode 100644 index 8cade1318fb..00000000000 --- a/infra/charts/feast/charts/grafana/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.vscode -.project -.idea/ -*.tmproj -OWNERS diff --git a/infra/charts/feast/charts/grafana/Chart.yaml b/infra/charts/feast/charts/grafana/Chart.yaml deleted file mode 100644 index b8d5e3eded4..00000000000 --- a/infra/charts/feast/charts/grafana/Chart.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -name: grafana -version: 5.0.5 -appVersion: 6.6.2 -kubeVersion: "^1.8.0-0" -description: The leading tool for querying and visualizing time series and metrics. -home: https://grafana.net -icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png -sources: - - https://github.com/grafana/grafana -maintainers: - - name: zanhsieh - email: zanhsieh@gmail.com - - name: rtluckie - email: rluckie@cisco.com - - name: maorfr - email: maor.friedman@redhat.com -engine: gotpl -tillerVersion: ">=2.12.0" diff --git a/infra/charts/feast/charts/grafana/README.md b/infra/charts/feast/charts/grafana/README.md deleted file mode 100644 index 5003f778f1a..00000000000 --- a/infra/charts/feast/charts/grafana/README.md +++ /dev/null @@ -1,321 +0,0 @@ -# Grafana Helm Chart - -* Installs the web dashboarding system [Grafana](http://grafana.org/) - -## TL;DR; - -```console -$ helm install stable/grafana -``` - -## Installing the Chart - -To install the chart with the release name `my-release`: - -```console -$ helm install --name my-release stable/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. - -## Configuration - -| Parameter | Description | Default | -|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| -| `replicas` | Number of nodes | `1` | -| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | -| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `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, "fsGroup": 472}` | -| `priorityClassName` | Name of Priority Class to assign pods | `nil` | -| `image.repository` | Image repository | `grafana/grafana` | -| `image.tag` | Image tag (`Must be >= 5.0.0`) | `6.6.2` | -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `image.pullSecrets` | Image pull secrets | `{}` | -| `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.targetPort` | Internal service is port | `3000` | -| `service.nodePort` | Kubernetes service nodePort | `nil` | -| `service.annotations` | Service annotations | `{}` | -| `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) | `[]` | -| `serivce.externalIPs` | service external IP addresses | `[]` | -| `ingress.enabled` | Enables Ingress | `false` | -| `ingress.annotations` | Ingress annotations | `{}` | -| `ingress.labels` | Custom labels | `{}` | -| `ingress.path` | Ingress accepted path | `/` | -| `ingress.hosts` | Ingress accepted hostnames | `[]` | -| `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-alb-ingress-controller/guide/ingress/annotation/#actions). | `[]` | -| `ingress.tls` | Ingress TLS configuration | `[]` | -| `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 | `{}` | -| `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 | `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.subPath` | Mount a sub dir of the persistent volume | `nil` | -| `initChownData.enabled` | If false, don't reset data ownership at startup | true | -| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | -| `initChownData.image.tag` | init-chown-data container image tag | `latest` | -| `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. | `{}` | -| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment | `""` | -| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret | `{}` | -| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | -| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | -| `extraConfigmapMounts` | Additional grafana server configMap volume mounts | `[]` | -| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | -| `plugins` | Plugins to be loaded along with Grafana | `[]` | -| `datasources` | Configure grafana datasources (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 | `{}` | -| `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` | -| `sidecar.image` | Sidecar image | `kiwigrid/k8s-sidecar:0.1.99` | -| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | -| `sidecar.resources` | Sidecar resources | `{}` | -| `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.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.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.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` | If specified, the sidecar will search for dashboard 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 | `nil` | -| `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.searchNamespace` | If specified, the sidecar will search for datasources 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 | `nil` | -| `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. | `""` | -| `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.annotations` | ServiceAccount annotations | | -| `serviceAccount.create` | Create service account | `true` | -| `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` | `` | -| `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.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `true` | -| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `true` | -| `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` | -| `testFramework.enabled` | Whether to create test-related resources | `true` | -| `testFramework.image` | `test-framework` image repository. | `bats/bats` | -| `testFramework.tag` | `test-framework` image tag. | `v1.1.0` | -| `testFramework.securityContext` | `test-framework` securityContext | `{}` | -| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | -| `downloadDashboardsImage.repository` | Curl docker image repo | `curlimages/curl` | -| `downloadDashboardsImage.tag` | Curl docker image tag | `7.68.0` | -| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | -| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | - -### Example of extraVolumeMounts - -```yaml -- extraVolumeMounts: - - name: plugins - mountPath: /var/lib/grafana/plugins - subPath: configs/grafana/plugins - existingClaim: existing-grafana-claim - readOnly: false -``` - -## 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 - local-dashboard: - url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json -``` - -## BASE64 dashboards - -Dashboards could be storaged in 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: https://yourgerritserver/a/{project-name}/branches/{branch-id}/files/{file-id}/content where {project-name} and -{file-id} usualy 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 https://yourgerritserver/a/user%2Frepo/branches/master/files/dir1%2Fdir2%2Fdashboard/content - -## 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: -``` -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. The secrets must be created before `helm install` so -that the datasources init container can list the secrets. - -Secrets are recommended over configmaps for this usecase because datasources usually contain private -data like usernames and passwords. Secrets are the more appropriate cluster ressource to manage those. - -Example datasource config adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): -``` -apiVersion: v1 -kind: Secret -metadata: - name: sample-grafana-datasource - labels: - grafana_datasource: "1" -type: Opaque -stringData: - datasource.yaml: |- - # config file version - apiVersion: 1 - - # list of datasources that should be deleted from the database - deleteDatasources: - - name: Graphite - orgId: 1 - - # list of datasources to insert/update depending - # whats available in the database - 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 - -``` - diff --git a/infra/charts/feast/charts/grafana/ci/default-values.yaml b/infra/charts/feast/charts/grafana/ci/default-values.yaml deleted file mode 100644 index fc2ba605ada..00000000000 --- a/infra/charts/feast/charts/grafana/ci/default-values.yaml +++ /dev/null @@ -1 +0,0 @@ -# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/infra/charts/feast/charts/grafana/ci/with-dashboard-json-values.yaml b/infra/charts/feast/charts/grafana/ci/with-dashboard-json-values.yaml deleted file mode 100644 index e0c4e41687a..00000000000 --- a/infra/charts/feast/charts/grafana/ci/with-dashboard-json-values.yaml +++ /dev/null @@ -1,53 +0,0 @@ -dashboards: - my-provider: - my-awesome-dashboard: - # An empty but valid dashboard - json: | - { - "__inputs": [], - "__requires": [ - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "6.3.5" - } - ], - "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": null, - "links": [], - "panels": [], - "schemaVersion": 19, - "style": "dark", - "tags": [], - "templating": { - "list": [] - }, - "time": { - "from": "now-6h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": ["5s"] - }, - "timezone": "", - "title": "Dummy Dashboard", - "uid": "IdcYQooWk", - "version": 1 - } - datasource: Prometheus diff --git a/infra/charts/feast/charts/grafana/ci/with-dashboard-values.yaml b/infra/charts/feast/charts/grafana/ci/with-dashboard-values.yaml deleted file mode 100644 index 7b662c5fd46..00000000000 --- a/infra/charts/feast/charts/grafana/ci/with-dashboard-values.yaml +++ /dev/null @@ -1,19 +0,0 @@ -dashboards: - my-provider: - my-awesome-dashboard: - gnetId: 10000 - revision: 1 - datasource: Prometheus -dashboardProviders: - dashboardproviders.yaml: - apiVersion: 1 - providers: - - name: 'my-provider' - orgId: 1 - folder: '' - type: file - updateIntervalSeconds: 10 - disableDeletion: true - editable: true - options: - path: /var/lib/grafana/dashboards/my-provider diff --git a/infra/charts/feast/charts/grafana/dashboards/custom-dashboard.json b/infra/charts/feast/charts/grafana/dashboards/custom-dashboard.json deleted file mode 100644 index 9e26dfeeb6e..00000000000 --- a/infra/charts/feast/charts/grafana/dashboards/custom-dashboard.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/infra/charts/feast/charts/grafana/templates/NOTES.txt b/infra/charts/feast/charts/grafana/templates/NOTES.txt deleted file mode 100644 index 6e1436e9027..00000000000 --- a/infra/charts/feast/charts/grafana/templates/NOTES.txt +++ /dev/null @@ -1,53 +0,0 @@ -1. Get your '{{ .Values.adminUser }}' user password by running: - - kubectl get secret --namespace {{ template "grafana.namespace" . }} {{ template "grafana.fullname" . }} -o jsonpath="{.data.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: - - {{ template "grafana.fullname" . }}.{{ template "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 - 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 {{ template "grafana.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "grafana.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ template "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 {{ template "grafana.namespace" . }} -w {{ template "grafana.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ template "grafana.namespace" . }} {{ template "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 {{ template "grafana.namespace" . }} -l "app={{ template "grafana.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace {{ template "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/infra/charts/feast/charts/grafana/templates/_helpers.tpl b/infra/charts/feast/charts/grafana/templates/_helpers.tpl deleted file mode 100644 index 6b08bd1af43..00000000000 --- a/infra/charts/feast/charts/grafana/templates/_helpers.tpl +++ /dev/null @@ -1,82 +0,0 @@ -{{/* 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 .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end -}} - -{{/* -Selector labels -*/}} -{{- define "grafana.selectorLabels" -}} -app.kubernetes.io/name: {{ include "grafana.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end -}} diff --git a/infra/charts/feast/charts/grafana/templates/_pod.tpl b/infra/charts/feast/charts/grafana/templates/_pod.tpl deleted file mode 100644 index e0e6e6fc584..00000000000 --- a/infra/charts/feast/charts/grafana/templates/_pod.tpl +++ /dev/null @@ -1,369 +0,0 @@ -{{- define "grafana.pod" -}} -{{- if .Values.schedulerName }} -schedulerName: "{{ .Values.schedulerName }}" -{{- end }} -serviceAccountName: {{ template "grafana.serviceAccountName" . }} -{{- if .Values.schedulerName }} -schedulerName: "{{ .Values.schedulerName }}" -{{- end }} -{{- if .Values.securityContext }} -securityContext: -{{ toYaml .Values.securityContext | indent 2 }} -{{- end }} -{{- if .Values.priorityClassName }} -priorityClassName: {{ .Values.priorityClassName }} -{{- end }} -{{- if ( or .Values.persistence.enabled .Values.dashboards .Values.extraInitContainers) }} -initContainers: -{{- end }} -{{- if ( and .Values.persistence.enabled .Values.initChownData.enabled ) }} - - name: init-chown-data - image: "{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}" - imagePullPolicy: {{ .Values.initChownData.image.pullPolicy }} - securityContext: - runAsUser: 0 - command: ["chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsUser }}", "/var/lib/grafana"] - resources: -{{ toYaml .Values.initChownData.resources | indent 6 }} - volumeMounts: - - name: storage - mountPath: "/var/lib/grafana" -{{- if .Values.persistence.subPath }} - subPath: {{ .Values.persistence.subPath }} -{{- end }} -{{- end }} -{{- if .Values.dashboards }} - - name: download-dashboards - image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}" - imagePullPolicy: {{ .Values.downloadDashboardsImage.pullPolicy }} - command: ["/bin/sh"] - args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh /etc/grafana/download_dashboards.sh" ] - env: -{{- range $key, $value := .Values.downloadDashboards.env }} - - name: "{{ $key }}" - value: "{{ $value }}" -{{- end }} - volumeMounts: - - name: config - mountPath: "/etc/grafana/download_dashboards.sh" - subPath: download_dashboards.sh - - name: storage - mountPath: "/var/lib/grafana" -{{- if .Values.persistence.subPath }} - subPath: {{ .Values.persistence.subPath }} -{{- end }} - {{- range .Values.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - readOnly: {{ .readOnly }} - {{- end }} -{{- end }} -{{- if .Values.extraInitContainers }} -{{ toYaml .Values.extraInitContainers | indent 2 }} -{{- end }} -{{- if .Values.image.pullSecrets }} -imagePullSecrets: -{{- range .Values.image.pullSecrets }} - - name: {{ . }} -{{- end}} -{{- end }} -containers: -{{- if .Values.sidecar.dashboards.enabled }} - - name: {{ template "grafana.name" . }}-sc-dashboard - image: "{{ .Values.sidecar.image }}" - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - - name: METHOD - value: {{ .Values.sidecar.dashboards.watchMethod }} - - name: LABEL - value: "{{ .Values.sidecar.dashboards.label }}" - - name: FOLDER - value: "{{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}" - - name: RESOURCE - value: "both" - {{- if .Values.sidecar.dashboards.searchNamespace }} - - name: NAMESPACE - value: "{{ .Values.sidecar.dashboards.searchNamespace }}" - {{- end }} - {{- if .Values.sidecar.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: "{{ .Values.sidecar.skipTlsVerify }}" - {{- end }} - resources: -{{ toYaml .Values.sidecar.resources | indent 6 }} - volumeMounts: - - name: sc-dashboard-volume - mountPath: {{ .Values.sidecar.dashboards.folder | quote }} -{{- end}} -{{- if .Values.sidecar.datasources.enabled }} - - name: {{ template "grafana.name" . }}-sc-datasources - image: "{{ .Values.sidecar.image }}" - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - - name: METHOD - value: {{ .Values.sidecar.datasources.watchMethod }} - - name: LABEL - value: "{{ .Values.sidecar.datasources.label }}" - - name: FOLDER - value: "/etc/grafana/provisioning/datasources" - - name: RESOURCE - value: "both" - {{- if .Values.sidecar.datasources.searchNamespace }} - - name: NAMESPACE - value: "{{ .Values.sidecar.datasources.searchNamespace }}" - {{- end }} - {{- if .Values.sidecar.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: "{{ .Values.sidecar.skipTlsVerify }}" - {{- end }} - resources: -{{ toYaml .Values.sidecar.resources | indent 6 }} - volumeMounts: - - name: sc-datasources-volume - mountPath: "/etc/grafana/provisioning/datasources" -{{- end}} - - name: {{ .Chart.Name }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - {{- if .Values.command }} - command: - {{- range .Values.command }} - - {{ . }} - {{- end }} - {{- 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: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath | default "" }} - readOnly: {{ .readOnly }} - {{- end }} - - name: storage - mountPath: "/var/lib/grafana" -{{- if .Values.persistence.subPath }} - subPath: {{ .Values.persistence.subPath }} -{{- end }} -{{- if .Values.dashboards }} -{{- range $provider, $dashboards := .Values.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 -}} -{{- if .Values.dashboardsConfigMaps }} -{{- range (keys .Values.dashboardsConfigMaps | sortAlpha) }} - - name: dashboards-{{ . }} - mountPath: "/var/lib/grafana/dashboards/{{ . }}" -{{- end }} -{{- end }} -{{- if .Values.datasources }} - - name: config - mountPath: "/etc/grafana/provisioning/datasources/datasources.yaml" - subPath: datasources.yaml -{{- end }} -{{- if .Values.notifiers }} - - name: config - mountPath: "/etc/grafana/provisioning/notifiers/notifiers.yaml" - subPath: notifiers.yaml -{{- end }} -{{- if .Values.dashboardProviders }} - - name: config - mountPath: "/etc/grafana/provisioning/dashboards/dashboardproviders.yaml" - subPath: dashboardproviders.yaml -{{- 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}} - {{- range .Values.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - readOnly: {{ .readOnly }} - {{- 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.service.portName }} - containerPort: {{ .Values.service.port }} - protocol: TCP - - name: {{ .Values.podPortName }} - containerPort: 3000 - protocol: TCP - env: - {{- if not .Values.env.GF_SECURITY_ADMIN_USER }} - - name: GF_SECURITY_ADMIN_USER - valueFrom: - secretKeyRef: - name: {{ .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) }} - - name: GF_SECURITY_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: {{ .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: {{ template "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 }} - {{- range $key, $value := .Values.envValueFrom }} - - name: {{ $key | quote }} - valueFrom: -{{ toYaml $value | indent 10 }} - {{- end }} -{{- range $key, $value := .Values.env }} - - name: "{{ $key }}" - value: "{{ $value }}" -{{- end }} - {{- if .Values.envFromSecret }} - envFrom: - - secretRef: - name: {{ .Values.envFromSecret }} - {{- end }} - {{- if .Values.envRenderSecret }} - envFrom: - - secretRef: - name: {{ template "grafana.fullname" . }}-env - {{- end }} - livenessProbe: -{{ toYaml .Values.livenessProbe | indent 6 }} - readinessProbe: -{{ toYaml .Values.readinessProbe | indent 6 }} - resources: -{{ toYaml .Values.resources | indent 6 }} -{{- with .Values.extraContainers }} -{{ tpl . $ | indent 2 }} -{{- end }} -{{- with .Values.nodeSelector }} -nodeSelector: -{{ toYaml . | indent 2 }} -{{- end }} -{{- with .Values.affinity }} -affinity: -{{ toYaml . | indent 2 }} -{{- end }} -{{- with .Values.tolerations }} -tolerations: -{{ toYaml . | indent 2 }} -{{- end }} -volumes: - - name: config - configMap: - name: {{ template "grafana.fullname" . }} -{{- range .Values.extraConfigmapMounts }} - - name: {{ .name }} - configMap: - name: {{ .configMap }} -{{- end }} - {{- if .Values.dashboards }} - {{- range (keys .Values.dashboards | sortAlpha) }} - - name: dashboards-{{ . }} - configMap: - name: {{ template "grafana.fullname" $ }}-dashboards-{{ . }} - {{- end }} - {{- end }} - {{- if .Values.dashboardsConfigMaps }} - {{ $root := . }} - {{- 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: {{ template "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: {{ .Values.persistence.existingClaim | default (include "grafana.fullname" .) }} -{{- else if and .Values.persistence.enabled (eq .Values.persistence.type "statefulset") }} -# nothing -{{- else }} - - name: storage - emptyDir: {} -{{- end -}} -{{- if .Values.sidecar.dashboards.enabled }} - - name: sc-dashboard-volume - emptyDir: {} -{{- if .Values.sidecar.dashboards.SCProvider }} - - name: sc-dashboard-provider - configMap: - name: {{ template "grafana.fullname" . }}-config-dashboards -{{- end }} -{{- end }} -{{- if .Values.sidecar.datasources.enabled }} - - name: sc-datasources-volume - emptyDir: {} -{{- end -}} -{{- range .Values.extraSecretMounts }} - - name: {{ .name }} - secret: - secretName: {{ .secretName }} - defaultMode: {{ .defaultMode }} -{{- end }} -{{- range .Values.extraVolumeMounts }} - - name: {{ .name }} - persistentVolumeClaim: - claimName: {{ .existingClaim }} -{{- end }} -{{- range .Values.extraEmptyDirMounts }} - - name: {{ .name }} - emptyDir: {} -{{- end -}} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/clusterrole.yaml b/infra/charts/feast/charts/grafana/templates/clusterrole.yaml deleted file mode 100644 index b3ef6ab3bf2..00000000000 --- a/infra/charts/feast/charts/grafana/templates/clusterrole.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- if and .Values.rbac.create (not .Values.rbac.namespaced) }} -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- with .Values.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} - name: {{ template "grafana.fullname" . }}-clusterrole -{{- if or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.rbac.extraClusterRoleRules) }} -rules: -{{- if or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled }} -- apiGroups: [""] # "" indicates the core API group - resources: ["configmaps", "secrets"] - verbs: ["get", "watch", "list"] -{{- end}} -{{- with .Values.rbac.extraClusterRoleRules }} -{{ toYaml . | indent 0 }} -{{- end}} -{{- else }} -rules: [] -{{- end}} -{{- end}} diff --git a/infra/charts/feast/charts/grafana/templates/clusterrolebinding.yaml b/infra/charts/feast/charts/grafana/templates/clusterrolebinding.yaml deleted file mode 100644 index 8ee08b2aa97..00000000000 --- a/infra/charts/feast/charts/grafana/templates/clusterrolebinding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.rbac.create (not .Values.rbac.namespaced) }} -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ template "grafana.fullname" . }}-clusterrolebinding - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- with .Values.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -subjects: - - kind: ServiceAccount - name: {{ template "grafana.serviceAccountName" . }} - namespace: {{ template "grafana.namespace" . }} -roleRef: - kind: ClusterRole - name: {{ template "grafana.fullname" . }}-clusterrole - apiGroup: rbac.authorization.k8s.io -{{- end -}} diff --git a/infra/charts/feast/charts/grafana/templates/configmap-dashboard-provider.yaml b/infra/charts/feast/charts/grafana/templates/configmap-dashboard-provider.yaml deleted file mode 100644 index af5d464b688..00000000000 --- a/infra/charts/feast/charts/grafana/templates/configmap-dashboard-provider.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- if .Values.sidecar.dashboards.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- with .Values.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} - name: {{ template "grafana.fullname" . }}-config-dashboards - namespace: {{ template "grafana.namespace" . }} -data: - provider.yaml: |- - apiVersion: 1 - providers: - - name: '{{ .Values.sidecar.dashboards.provider.name }}' - orgId: {{ .Values.sidecar.dashboards.provider.orgid }} - folder: '{{ .Values.sidecar.dashboards.provider.folder }}' - type: {{ .Values.sidecar.dashboards.provider.type }} - disableDeletion: {{ .Values.sidecar.dashboards.provider.disableDelete }} - allowUiUpdates: {{ .Values.sidecar.dashboards.provider.allowUiUpdates }} - options: - path: {{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }} -{{- end}} diff --git a/infra/charts/feast/charts/grafana/templates/configmap.yaml b/infra/charts/feast/charts/grafana/templates/configmap.yaml deleted file mode 100644 index 00c69572746..00000000000 --- a/infra/charts/feast/charts/grafana/templates/configmap.yaml +++ /dev/null @@ -1,69 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -data: -{{- if .Values.plugins }} - plugins: {{ join "," .Values.plugins }} -{{- end }} - grafana.ini: | -{{- range $key, $value := index .Values "grafana.ini" }} - [{{ $key }}] - {{- range $elem, $elemVal := $value }} - {{ $elem }} = {{ $elemVal }} - {{- end }} -{{- end }} - -{{- if .Values.datasources }} -{{ $root := . }} - {{- range $key, $value := .Values.datasources }} - {{ $key }}: | -{{ tpl (toYaml $value | indent 4) $root }} - {{- end -}} -{{- end -}} - -{{- if .Values.notifiers }} - {{- range $key, $value := .Values.notifiers }} - {{ $key }}: | -{{ toYaml $value | indent 4 }} - {{- end -}} -{{- end -}} - -{{- if .Values.dashboardProviders }} - {{- range $key, $value := .Values.dashboardProviders }} - {{ $key }}: | -{{ toYaml $value | indent 4 }} - {{- end -}} -{{- 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 }} - - {{- 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 }} - -H "Accept: application/json" \ - -H "Content-Type: application/json;charset=UTF-8" \ - {{ 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 }}| sed 's|\"datasource\":[^,]*|\"datasource\": \"{{ $value.datasource }}\"|g'{{ end }}{{- if $value.b64content -}} | base64 -d {{- end -}} \ - > /var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json - {{- end -}} - {{- end }} - {{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/dashboards-json-configmap.yaml b/infra/charts/feast/charts/grafana/templates/dashboards-json-configmap.yaml deleted file mode 100644 index 59e0be64157..00000000000 --- a/infra/charts/feast/charts/grafana/templates/dashboards-json-configmap.yaml +++ /dev/null @@ -1,35 +0,0 @@ -{{- if .Values.dashboards }} -{{ $files := .Files }} -{{- range $provider, $dashboards := .Values.dashboards }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "grafana.fullname" $ }}-dashboards-{{ $provider }} - namespace: {{ template "grafana.namespace" $ }} - labels: - {{- include "grafana.labels" $ | nindent 4 }} - dashboard-provider: {{ $provider }} -{{- if $dashboards }} -data: -{{- $dashboardFound := false }} -{{- range $key, $value := $dashboards }} -{{- if (or (hasKey $value "json") (hasKey $value "file")) }} -{{- $dashboardFound = true }} -{{ print $key | indent 2 }}.json: -{{- if hasKey $value "json" }} - |- -{{ $value.json | indent 6 }} -{{- end }} -{{- if hasKey $value "file" }} -{{ toYaml ( $files.Get $value.file ) | indent 4}} -{{- end }} -{{- end }} -{{- end }} -{{- if not $dashboardFound }} - {} -{{- end }} -{{- end }} ---- -{{- end }} - -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/deployment.yaml b/infra/charts/feast/charts/grafana/templates/deployment.yaml deleted file mode 100644 index 27a4b76d474..00000000000 --- a/infra/charts/feast/charts/grafana/templates/deployment.yaml +++ /dev/null @@ -1,44 +0,0 @@ -{{ if (or (not .Values.persistence.enabled) (eq .Values.persistence.type "pvc")) }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- if .Values.labels }} -{{ toYaml .Values.labels | indent 4 }} -{{- end }} -{{- with .Values.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 6 }} -{{- with .Values.deploymentStrategy }} - strategy: -{{ toYaml . | trim | indent 4 }} -{{- end }} - template: - metadata: - labels: - {{- include "grafana.selectorLabels" . | nindent 8 }} -{{- with .Values.podLabels }} -{{ toYaml . | indent 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 (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) }} - checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} -{{- end }} -{{- with .Values.podAnnotations }} -{{ toYaml . | indent 8 }} -{{- end }} - spec: - {{- include "grafana.pod" . | nindent 6 }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/headless-service.yaml b/infra/charts/feast/charts/grafana/templates/headless-service.yaml deleted file mode 100644 index 2fa816e0450..00000000000 --- a/infra/charts/feast/charts/grafana/templates/headless-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset")}} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "grafana.fullname" . }}-headless - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- with .Values.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: - clusterIP: None - selector: - {{- include "grafana.selectorLabels" . | nindent 4 }} - type: ClusterIP -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/ingress.yaml b/infra/charts/feast/charts/grafana/templates/ingress.yaml deleted file mode 100644 index 202efb36196..00000000000 --- a/infra/charts/feast/charts/grafana/templates/ingress.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- if .Values.ingress.enabled -}} -{{- $fullName := include "grafana.fullname" . -}} -{{- $servicePort := .Values.service.port -}} -{{- $ingressPath := .Values.ingress.path -}} -{{- $extraPaths := .Values.ingress.extraPaths -}} -{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} -apiVersion: networking.k8s.io/v1beta1 -{{ else }} -apiVersion: extensions/v1beta1 -{{ end -}} -kind: Ingress -metadata: - name: {{ $fullName }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- if .Values.ingress.labels }} -{{ toYaml .Values.ingress.labels | indent 4 }} -{{- end }} -{{- with .Values.ingress.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: -{{- if .Values.ingress.tls }} - tls: -{{ toYaml .Values.ingress.tls | indent 4 }} -{{- end }} - rules: - {{- range .Values.ingress.hosts }} - - host: {{ . }} - http: - paths: -{{ if $extraPaths }} -{{ toYaml $extraPaths | indent 10 }} -{{- end }} - - path: {{ $ingressPath }} - backend: - serviceName: {{ $fullName }} - servicePort: {{ $servicePort }} - {{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/poddisruptionbudget.yaml b/infra/charts/feast/charts/grafana/templates/poddisruptionbudget.yaml deleted file mode 100644 index d6f230a8f25..00000000000 --- a/infra/charts/feast/charts/grafana/templates/poddisruptionbudget.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- if .Values.podDisruptionBudget }} -apiVersion: policy/v1beta1 -kind: PodDisruptionBudget -metadata: - name: {{ template "grafana.name" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- if .Values.labels }} -{{ toYaml .Values.labels | indent 4 }} -{{- end }} -spec: -{{- if .Values.podDisruptionBudget.minAvailable }} - minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} -{{- end }} -{{- if .Values.podDisruptionBudget.maxUnavailable }} - maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} -{{- end }} - selector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 6 }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/podsecuritypolicy.yaml b/infra/charts/feast/charts/grafana/templates/podsecuritypolicy.yaml deleted file mode 100644 index c5e6ba05ead..00000000000 --- a/infra/charts/feast/charts/grafana/templates/podsecuritypolicy.yaml +++ /dev/null @@ -1,52 +0,0 @@ -{{- if .Values.rbac.pspEnabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - annotations: - seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' - seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' - {{- if .Values.rbac.pspUseAppArmor }} - apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' - apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' - {{- end }} -spec: - privileged: false - allowPrivilegeEscalation: false - requiredDropCapabilities: - # Default set from Docker, without DAC_OVERRIDE or CHOWN - - FOWNER - - FSETID - - KILL - - SETGID - - SETUID - - SETPCAP - - NET_BIND_SERVICE - - NET_RAW - - SYS_CHROOT - - MKNOD - - AUDIT_WRITE - - SETFCAP - volumes: - - 'configMap' - - 'emptyDir' - - 'projected' - - 'secret' - - 'downwardAPI' - - 'persistentVolumeClaim' - hostNetwork: false - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' - supplementalGroups: - rule: 'RunAsAny' - fsGroup: - rule: 'RunAsAny' - readOnlyRootFilesystem: false -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/pvc.yaml b/infra/charts/feast/charts/grafana/templates/pvc.yaml deleted file mode 100644 index 4727d0aa14c..00000000000 --- a/infra/charts/feast/charts/grafana/templates/pvc.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "pvc")}} -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.persistence.annotations }} - annotations: -{{ toYaml . | indent 4 }} - {{- end }} - {{- with .Values.persistence.finalizers }} - finalizers: -{{ toYaml . | indent 4 }} - {{- end }} -spec: - accessModes: - {{- range .Values.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} - {{- if .Values.persistence.storageClassName }} - storageClassName: {{ .Values.persistence.storageClassName }} - {{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/grafana/templates/role.yaml b/infra/charts/feast/charts/grafana/templates/role.yaml deleted file mode 100644 index c95c1d04241..00000000000 --- a/infra/charts/feast/charts/grafana/templates/role.yaml +++ /dev/null @@ -1,32 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: Role -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- with .Values.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -{{- if or .Values.rbac.pspEnabled (and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.rbac.extraRoleRules))) }} -rules: -{{- if .Values.rbac.pspEnabled }} -- apiGroups: ['extensions'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: [{{ template "grafana.fullname" . }}] -{{- end }} -{{- if and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled) }} -- apiGroups: [""] # "" indicates the core API group - resources: ["configmaps", "secrets"] - verbs: ["get", "watch", "list"] -{{- end }} -{{- with .Values.rbac.extraRoleRules }} -{{ toYaml . | indent 0 }} -{{- end}} -{{- else }} -rules: [] -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/rolebinding.yaml b/infra/charts/feast/charts/grafana/templates/rolebinding.yaml deleted file mode 100644 index c42229bf925..00000000000 --- a/infra/charts/feast/charts/grafana/templates/rolebinding.yaml +++ /dev/null @@ -1,27 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- with .Values.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "grafana.fullname" . }} -subjects: -- kind: ServiceAccount - name: {{ template "grafana.serviceAccountName" . }} - namespace: {{ template "grafana.namespace" . }} -{{- if .Values.rbac.namespaced }} -roleRef: - kind: Role - name: {{ template "grafana.fullname" . }} - apiGroup: rbac.authorization.k8s.io -{{- end }} -{{- end -}} diff --git a/infra/charts/feast/charts/grafana/templates/secret-env.yaml b/infra/charts/feast/charts/grafana/templates/secret-env.yaml deleted file mode 100644 index 5c09313e665..00000000000 --- a/infra/charts/feast/charts/grafana/templates/secret-env.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if .Values.envRenderSecret }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "grafana.fullname" . }}-env - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -type: Opaque -data: -{{- range $key, $val := .Values.envRenderSecret }} - {{ $key }}: {{ $val | b64enc | quote }} -{{- end -}} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/secret.yaml b/infra/charts/feast/charts/grafana/templates/secret.yaml deleted file mode 100644 index f7ee9956b3c..00000000000 --- a/infra/charts/feast/charts/grafana/templates/secret.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -type: Opaque -data: - admin-user: {{ .Values.adminUser | b64enc | quote }} - {{- if .Values.adminPassword }} - admin-password: {{ .Values.adminPassword | b64enc | quote }} - {{- else }} - admin-password: {{ randAlphaNum 40 | b64enc | quote }} - {{- end }} - {{- if not .Values.ldap.existingSecret }} - ldap-toml: {{ .Values.ldap.config | b64enc | quote }} - {{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/service.yaml b/infra/charts/feast/charts/grafana/templates/service.yaml deleted file mode 100644 index e06c27df32a..00000000000 --- a/infra/charts/feast/charts/grafana/templates/service.yaml +++ /dev/null @@ -1,46 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- if .Values.service.labels }} -{{ toYaml .Values.service.labels | indent 4 }} -{{- end }} -{{- with .Values.service.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: -{{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} - type: ClusterIP - {{- if .Values.service.clusterIP }} - clusterIP: {{ .Values.service.clusterIP }} - {{end}} -{{- else if eq .Values.service.type "LoadBalancer" }} - type: {{ .Values.service.type }} - {{- if .Values.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.service.loadBalancerIP }} - {{- end }} - {{- if .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: -{{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} - {{- end -}} -{{- else }} - type: {{ .Values.service.type }} -{{- end }} -{{- if .Values.service.externalIPs }} - externalIPs: -{{ toYaml .Values.service.externalIPs | indent 4 }} -{{- end }} - ports: - - name: {{ .Values.service.portName }} - port: {{ .Values.service.port }} - protocol: TCP - targetPort: {{ .Values.service.targetPort }} -{{ if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} - nodePort: {{.Values.service.nodePort}} -{{ end }} - selector: - {{- include "grafana.selectorLabels" . | nindent 4 }} diff --git a/infra/charts/feast/charts/grafana/templates/serviceaccount.yaml b/infra/charts/feast/charts/grafana/templates/serviceaccount.yaml deleted file mode 100644 index 7576eeef064..00000000000 --- a/infra/charts/feast/charts/grafana/templates/serviceaccount.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if .Values.serviceAccount.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- with .Values.serviceAccount.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} - name: {{ template "grafana.serviceAccountName" . }} - namespace: {{ template "grafana.namespace" . }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/statefulset.yaml b/infra/charts/feast/charts/grafana/templates/statefulset.yaml deleted file mode 100644 index afc26b7c2f5..00000000000 --- a/infra/charts/feast/charts/grafana/templates/statefulset.yaml +++ /dev/null @@ -1,44 +0,0 @@ -{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset")}} -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ template "grafana.fullname" . }} - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- with .Values.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 6 }} - serviceName: {{ template "grafana.fullname" . }}-headless - template: - metadata: - labels: - {{- include "grafana.selectorLabels" . | nindent 8 }} - 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 not .Values.admin.existingSecret }} - checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} -{{- end }} -{{- with .Values.podAnnotations }} -{{ toYaml . | indent 8 }} -{{- end }} - spec: - {{- include "grafana.pod" . | nindent 6 }} - volumeClaimTemplates: - - metadata: - name: storage - spec: - accessModes: {{ .Values.persistence.accessModes }} - storageClassName: {{ .Values.persistence.storageClassName }} - resources: - requests: - storage: {{ .Values.persistence.size }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-configmap.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-configmap.yaml deleted file mode 100644 index ff53aaf1b36..00000000000 --- a/infra/charts/feast/charts/grafana/templates/tests/test-configmap.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.testFramework.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "grafana.fullname" . }}-test - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -data: - run.sh: |- - @test "Test Health" { - url="http://{{ template "grafana.fullname" . }}/api/health" - - code=$(wget --server-response --spider --timeout 10 --tries 1 ${url} 2>&1 | awk '/^ HTTP/{print $2}') - [ "$code" == "200" ] - } -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-podsecuritypolicy.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-podsecuritypolicy.yaml deleted file mode 100644 index eb5cbbcd701..00000000000 --- a/infra/charts/feast/charts/grafana/templates/tests/test-podsecuritypolicy.yaml +++ /dev/null @@ -1,29 +0,0 @@ -{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "grafana.fullname" . }}-test - namespace: {{ template "grafana.namespace" . }} - 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 - - secret -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-role.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-role.yaml deleted file mode 100644 index 6b10677ae76..00000000000 --- a/infra/charts/feast/charts/grafana/templates/tests/test-role.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ template "grafana.fullname" . }}-test - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -rules: -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: [{{ template "grafana.fullname" . }}-test] -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-rolebinding.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-rolebinding.yaml deleted file mode 100644 index 58fa5e78b56..00000000000 --- a/infra/charts/feast/charts/grafana/templates/tests/test-rolebinding.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "grafana.fullname" . }}-test - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "grafana.fullname" . }}-test -subjects: -- kind: ServiceAccount - name: {{ template "grafana.serviceAccountNameTest" . }} - namespace: {{ template "grafana.namespace" . }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test-serviceaccount.yaml b/infra/charts/feast/charts/grafana/templates/tests/test-serviceaccount.yaml deleted file mode 100644 index 5c335073371..00000000000 --- a/infra/charts/feast/charts/grafana/templates/tests/test-serviceaccount.yaml +++ /dev/null @@ -1,9 +0,0 @@ -{{- if and .Values.testFramework.enabled .Values.serviceAccount.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "grafana.labels" . | nindent 4 }} - name: {{ template "grafana.serviceAccountNameTest" . }} - namespace: {{ template "grafana.namespace" . }} -{{- end }} diff --git a/infra/charts/feast/charts/grafana/templates/tests/test.yaml b/infra/charts/feast/charts/grafana/templates/tests/test.yaml deleted file mode 100644 index 7b2475c62c9..00000000000 --- a/infra/charts/feast/charts/grafana/templates/tests/test.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- if .Values.testFramework.enabled }} -apiVersion: v1 -kind: Pod -metadata: - name: {{ template "grafana.fullname" . }}-test - labels: - {{- include "grafana.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": test-success - namespace: {{ template "grafana.namespace" . }} -spec: - serviceAccountName: {{ template "grafana.serviceAccountNameTest" . }} - {{- if .Values.testFramework.securityContext }} - securityContext: {{ toYaml .Values.testFramework.securityContext | nindent 4 }} - {{- end }} - {{- if .Values.image.pullSecrets }} - imagePullSecrets: - {{- range .Values.image.pullSecrets }} - - name: {{ . }} - {{- end}} - {{- end }} - {{- with .Values.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 4 }} - {{- end }} - {{- with .Values.affinity }} - affinity: -{{ toYaml . | indent 4 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: -{{ toYaml . | indent 4 }} - {{- end }} - containers: - - name: {{ .Release.Name }}-test - image: "{{ .Values.testFramework.image}}:{{ .Values.testFramework.tag }}" - command: ["/opt/bats/bin/bats", "-t", "/tests/run.sh"] - volumeMounts: - - mountPath: /tests - name: tests - readOnly: true - volumes: - - name: tests - configMap: - name: {{ template "grafana.fullname" . }}-test - restartPolicy: Never -{{- end }} diff --git a/infra/charts/feast/charts/grafana/values.yaml b/infra/charts/feast/charts/grafana/values.yaml deleted file mode 100644 index cb1467159df..00000000000 --- a/infra/charts/feast/charts/grafana/values.yaml +++ /dev/null @@ -1,485 +0,0 @@ -rbac: - create: true - pspEnabled: true - pspUseAppArmor: true - namespaced: false - extraRoleRules: [] - # - apiGroups: [] - # resources: [] - # verbs: [] - extraClusterRoleRules: [] - # - apiGroups: [] - # resources: [] - # verbs: [] -serviceAccount: - create: true - name: - nameTest: -# annotations: - -replicas: 1 - -## See `kubectl explain poddisruptionbudget.spec` for more -## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ -podDisruptionBudget: {} -# 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: grafana/grafana - tag: 6.6.2 - 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/ - ## - # pullSecrets: - # - myRegistrKeySecretName - -testFramework: - enabled: true - image: "bats/bats" - tag: "v1.1.0" - securityContext: {} - -securityContext: - runAsUser: 472 - fsGroup: 472 - - -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 - - -## Assign a PriorityClassName to pods if set -# priorityClassName: - -downloadDashboardsImage: - repository: curlimages/curl - tag: 7.68.0 - pullPolicy: IfNotPresent - -downloadDashboards: - env: {} - -## Pod Annotations -# podAnnotations: {} - -## Pod Labels -# podLabels: {} - -podPortName: grafana - -## 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: - type: ClusterIP - port: 80 - targetPort: 3000 - # targetPort: 4181 To be used with a proxy extraContainer - annotations: {} - labels: {} - portName: service - -ingress: - enabled: false - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - labels: {} - path: / - 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 - 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 -## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity -## -affinity: {} - -extraInitContainers: [] - -## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod -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 - -## 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 - # subPath: "" - # existingClaim: - -initChownData: - ## If false, data ownership will not be reset at startup - ## This allows the prometheus-server to be run with an arbitrary user - ## - enabled: true - - ## initChownData container image - ## - image: - repository: busybox - tag: "1.31.1" - 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 - - -# Administrator credentials when not using an existing secret (see below) -adminUser: admin -# adminPassword: strongpassword - -# Use an existing secret for the admin user. -admin: - 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" - -## Use an alternate scheduler, e.g. "stork". -## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ -## -# schedulerName: - -## Extra environment variables that will be pass onto deployment pods -env: {} - -## "valueFrom" environment variable references that will be added to deployment pods -## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core -## Renders in container spec as: -## env: -## ... -## - name: -## valueFrom: -## -envValueFrom: {} - -## 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 -envFromSecret: "" - -## Sensible environment variables that will be rendered as new secret object -## This can be useful for auth tokens, etc -envRenderSecret: {} - -## 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 - -## Additional grafana server volume mounts -# Defines additional volume mounts. -extraVolumeMounts: [] - # - name: extra-volume - # mountPath: /mnt/volume - # readOnly: true - # existingClaim: volume-claim - -## Pass the plugins you want installed as a list. -## -plugins: [] - # - digrich-bubblechart-panel - # - grafana-clock-panel - -## 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 - -## 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 - # local-dashboard-base64: - # url: https://example.com/repository/test-b64.json - # b64content: true - -## Reference to external ConfigMap per provider. Use provider name as key and ConfiMap 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/data - 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 -## 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: kiwigrid/k8s-sidecar:0.1.99 - imagePullPolicy: IfNotPresent - resources: {} -# limits: -# cpu: 100m -# memory: 100Mi -# requests: -# cpu: 50m -# memory: 50Mi - # skipTlsVerify Set to true to skip tls verification for kube api calls - # skipTlsVerify: true - dashboards: - enabled: false - ## 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 - SCProvider: true - # label that the configmaps with dashboards are marked with - label: grafana_dashboard - # 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 - # If specified, the sidecar will search for dashboard 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 - # 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 - datasources: - enabled: false - ## 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 - # label that the configmaps with datasources are marked with - label: grafana_datasource - # 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 - -## Override the deployment namespace -## -namespaceOverride: "" diff --git a/infra/charts/feast/charts/kafka-0.20.8.tgz b/infra/charts/feast/charts/kafka-0.20.8.tgz new file mode 100644 index 0000000000000000000000000000000000000000..f61be294aeaab0dce87d53c0f19e35a2854a6196 GIT binary patch literal 31688 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 literal 0 HcmV?d00001 diff --git a/infra/charts/feast/charts/kafka/.helmignore b/infra/charts/feast/charts/kafka/.helmignore deleted file mode 100644 index f0c13194444..00000000000 --- a/infra/charts/feast/charts/kafka/.helmignore +++ /dev/null @@ -1,21 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj diff --git a/infra/charts/feast/charts/kafka/Chart.yaml b/infra/charts/feast/charts/kafka/Chart.yaml deleted file mode 100755 index da92b400275..00000000000 --- a/infra/charts/feast/charts/kafka/Chart.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: v1 -description: Apache Kafka is publish-subscribe messaging rethought as a distributed - commit log. -name: kafka -version: 0.20.8 -appVersion: 5.0.1 -keywords: -- kafka -- zookeeper -- kafka statefulset -home: https://kafka.apache.org/ -sources: -- https://github.com/kubernetes/charts/tree/master/incubator/zookeeper -- https://github.com/Yolean/kubernetes-kafka -- https://github.com/confluentinc/cp-docker-images -- https://github.com/apache/kafka -maintainers: -- name: faraazkhan - email: faraaz@rationalizeit.us -- name: h0tbird - email: marc.villacorta@gmail.com -- name: benjigoldberg - email: ben@spothero.com -icon: https://kafka.apache.org/images/logo.png diff --git a/infra/charts/feast/charts/kafka/README.md b/infra/charts/feast/charts/kafka/README.md deleted file mode 100644 index c9f3b9c4d86..00000000000 --- a/infra/charts/feast/charts/kafka/README.md +++ /dev/null @@ -1,432 +0,0 @@ -# Apache Kafka Helm Chart - -This is an implementation of Kafka StatefulSet found here: - - * https://github.com/Yolean/kubernetes-kafka - -## Pre Requisites: - -* Kubernetes 1.3 with alpha APIs enabled and support for storage classes - -* PV support on underlying infrastructure - -* Requires at least `v2.0.0-beta.1` version of helm to support - dependency management with requirements.yaml - -## StatefulSet Details - -* https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ - -## StatefulSet Caveats - -* https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#limitations - -## Chart Details - -This chart will do the following: - -* Implement a dynamically scalable kafka cluster using Kubernetes StatefulSets - -* Implement a dynamically scalable zookeeper cluster as another Kubernetes StatefulSet required for the Kafka cluster above - -* Expose Kafka protocol endpoints via NodePort services (optional) - -### Installing the Chart - -To install the chart with the release name `my-kafka` in the default -namespace: - -``` -$ helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator -$ helm install --name my-kafka incubator/kafka -``` - -If using a dedicated namespace(recommended) then make sure the namespace -exists with: - -``` -$ helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator -$ kubectl create ns kafka -$ helm install --name my-kafka --namespace kafka incubator/kafka -``` - -This chart includes a ZooKeeper chart as a dependency to the Kafka -cluster in its `requirement.yaml` by default. The chart can be customized using the -following configurable parameters: - -| Parameter | Description | Default | -|------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------| -| `image` | Kafka Container image name | `confluentinc/cp-kafka` | -| `imageTag` | Kafka Container image tag | `5.0.1` | -| `imagePullPolicy` | Kafka Container pull policy | `IfNotPresent` | -| `replicas` | Kafka Brokers | `3` | -| `component` | Kafka k8s selector key | `kafka` | -| `resources` | Kafka resource requests and limits | `{}` | -| `securityContext` | Kafka containers security context | `{}` | -| `kafkaHeapOptions` | Kafka broker JVM heap options | `-Xmx1G-Xms1G` | -| `logSubPath` | Subpath under `persistence.mountPath` where kafka logs will be placed. | `logs` | -| `schedulerName` | Name of Kubernetes scheduler (other than the default) | `nil` | -| `serviceAccountName` | Name of Kubernetes serviceAccount. Useful when needing to pull images from custom repositories | `nil` | -| `priorityClassName` | Name of Kubernetes Pod PriorityClass. https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass | `nil` | -| `affinity` | Defines affinities and anti-affinities for pods as defined in: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity preferences | `{}` | -| `tolerations` | List of node tolerations for the pods. https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | `[]` | -| `headless.annotations` | List of annotations for the headless service. https://kubernetes.io/docs/concepts/services-networking/service/#headless-services | `[]` | -| `headless.targetPort` | Target port to be used for the headless service. This is not a required value. | `nil` | -| `headless.port` | Port to be used for the headless service. https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | `9092` | -| `external.enabled` | If True, exposes Kafka brokers via NodePort (PLAINTEXT by default) | `false` | -| `external.dns.useInternal` | If True, add Annotation for internal DNS service | `false` | -| `external.dns.useExternal` | If True, add Annotation for external DNS service | `true` | -| `external.servicePort` | TCP port configured at external services (one per pod) to relay from NodePort to the external listener port. | '19092' | -| `external.firstListenerPort` | TCP port which is added pod index number to arrive at the port used for NodePort and external listener port. | '31090' | -| `external.domain` | Domain in which to advertise Kafka external listeners. | `cluster.local` | -| `external.type` | Service Type. | `NodePort` | -| `external.distinct` | Distinct DNS entries for each created A record. | `false` | -| `external.annotations` | Additional annotations for the external service. | `{}` | -| `external.loadBalancerIP` | Add Static IP to the type Load Balancer. Depends on the provider if enabled | `[]` -| `external.loadBalancerSourceRanges` | Add IP ranges that are allowed to access the Load Balancer. | `[]` -| `podAnnotations` | Annotation to be added to Kafka pods | `{}` | -| `podLabels` | Labels to be added to Kafka pods | `{}` | -| `podDisruptionBudget` | Define a Disruption Budget for the Kafka Pods | `{}` | -| `envOverrides` | Add additional Environment Variables in the dictionary format | `{ zookeeper.sasl.enabled: "False" }` | -| `configurationOverrides` | `Kafka ` [configuration setting][brokerconfigs] overrides in the dictionary format | `{ "confluent.support.metrics.enable": false }` | -| `secrets` | Pass any secrets to the kafka pods. Each secret will be passed as an environment variable by default. The secret can also be mounted to a specific path if required. Environment variable names are generated as: `_` (All upper case) | `{}` | -| `additionalPorts` | Additional ports to expose on brokers. Useful when the image exposes metrics (like prometheus, etc.) through a javaagent instead of a sidecar | `{}` | -| `readinessProbe.initialDelaySeconds` | Number of seconds before probe is initiated. | `30` | -| `readinessProbe.periodSeconds` | How often (in seconds) to perform the probe. | `10` | -| `readinessProbe.timeoutSeconds` | Number of seconds after which the probe times out. | `5` | -| `readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed. | `1` | -| `readinessProbe.failureThreshold` | After the probe fails this many times, pod will be marked Unready. | `3` | -| `terminationGracePeriodSeconds` | Wait up to this many seconds for a broker to shut down gracefully, after which it is killed | `60` | -| `updateStrategy` | StatefulSet update strategy to use. | `{ type: "OnDelete" }` | -| `podManagementPolicy` | Start and stop pods in Parallel or OrderedReady (one-by-one.) Can not change after first release. | `OrderedReady` | -| `persistence.enabled` | Use a PVC to persist data | `true` | -| `persistence.size` | Size of data volume | `1Gi` | -| `persistence.mountPath` | Mount path of data volume | `/opt/kafka/data` | -| `persistence.storageClass` | Storage class of backing PVC | `nil` | -| `jmx.configMap.enabled` | Enable the default ConfigMap for JMX | `true` | -| `jmx.configMap.overrideConfig` | Allows config file to be generated by passing values to ConfigMap | `{}` | -| `jmx.configMap.overrideName` | Allows setting the name of the ConfigMap to be used | `""` | -| `jmx.port` | The jmx port which JMX style metrics are exposed (note: these are not scrapeable by Prometheus) | `5555` | -| `jmx.whitelistObjectNames` | Allows setting which JMX objects you want to expose to via JMX stats to JMX Exporter | (see `values.yaml`) | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `prometheus.jmx.resources` | Allows setting resource limits for jmx sidecar container | `{}` | -| `prometheus.jmx.enabled` | Whether or not to expose JMX metrics to Prometheus | `false` | -| `prometheus.jmx.image` | JMX Exporter container image | `solsson/kafka-prometheus-jmx-exporter@sha256` | -| `prometheus.jmx.imageTag` | JMX Exporter container image tag | `a23062396cd5af1acdf76512632c20ea6be76885dfc20cd9ff40fb23846557e8` | -| `prometheus.jmx.interval` | Interval that Prometheus scrapes JMX metrics when using Prometheus Operator | `10s` | -| `prometheus.jmx.scrapeTimeout` | Timeout that Prometheus scrapes JMX metrics when using Prometheus Operator | `10s` | -| `prometheus.jmx.port` | JMX Exporter Port which exposes metrics in Prometheus format for scraping | `5556` | -| `prometheus.kafka.enabled` | Whether or not to create a separate Kafka exporter | `false` | -| `prometheus.kafka.image` | Kafka Exporter container image | `danielqsj/kafka-exporter` | -| `prometheus.kafka.imageTag` | Kafka Exporter container image tag | `v1.2.0` | -| `prometheus.kafka.interval` | Interval that Prometheus scrapes Kafka metrics when using Prometheus Operator | `10s` | -| `prometheus.kafka.scrapeTimeout` | Timeout that Prometheus scrapes Kafka metrics when using Prometheus Operator | `10s` | -| `prometheus.kafka.port` | Kafka Exporter Port which exposes metrics in Prometheus format for scraping | `9308` | -| `prometheus.kafka.resources` | Allows setting resource limits for kafka-exporter pod | `{}` | -| `prometheus.kafka.affinity` | Defines affinities and anti-affinities for pods as defined in: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity preferences | `{}` | -| `prometheus.kafka.tolerations` | List of node tolerations for the pods. https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | `[]` | -| `prometheus.operator.enabled` | True if using the Prometheus Operator, False if not | `false` | -| `prometheus.operator.serviceMonitor.namespace` | Namespace in which to install the ServiceMonitor resource. Default to kube-prometheus install. | `monitoring` | -| `prometheus.operator.serviceMonitor.releaseNamespace` | Set namespace to release namespace. Default false | `false` | -| `prometheus.operator.serviceMonitor.selector` | Default to kube-prometheus install (CoreOS recommended), but should be set according to Prometheus install | `{ prometheus: kube-prometheus }` | -| `prometheus.operator.prometheusRule.enabled` | True to create a PrometheusRule resource for Prometheus Operator, False if not | `false` | -| `prometheus.operator.prometheusRule.namespace` | Namespace in which to install the PrometheusRule resource. Default to kube-prometheus install. | `monitoring` | -| `prometheus.operator.prometheusRule.releaseNamespace` | Set namespace to release namespace. Default false | `false` | -| `prometheus.operator.prometheusRule.selector` | Default to kube-prometheus install (CoreOS recommended), but should be set according to Prometheus install | `{ prometheus: kube-prometheus }` | -| `prometheus.operator.prometheusRule.rules` | Define the prometheus rules. See values file for examples | `{}` | -| `configJob.backoffLimit` | Number of retries before considering kafka-config job as failed | `6` | -| `topics` | List of topics to create & configure. Can specify name, partitions, replicationFactor, reassignPartitions, config. See values.yaml | `[]` (Empty list) | -| `zookeeper.enabled` | If True, installs Zookeeper Chart | `true` | -| `zookeeper.resources` | Zookeeper resource requests and limits | `{}` | -| `zookeeper.env` | Environmental variables provided to Zookeeper Zookeeper | `{ZK_HEAP_SIZE: "1G"}` | -| `zookeeper.storage` | Zookeeper Persistent volume size | `2Gi` | -| `zookeeper.image.PullPolicy` | Zookeeper Container pull policy | `IfNotPresent` | -| `zookeeper.url` | URL of Zookeeper Cluster (unneeded if installing Zookeeper Chart) | `""` | -| `zookeeper.port` | Port of Zookeeper Cluster | `2181` | -| `zookeeper.affinity` | Defines affinities and anti-affinities for pods as defined in: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity preferences | `{}` | -| `zookeeper.nodeSelector` | Node labels for pod assignment | `{}` | - -Specify parameters using `--set key=value[,key=value]` argument to `helm install` - -Alternatively a YAML file that specifies the values for the parameters can be provided like this: - -```bash -$ helm install --name my-kafka -f values.yaml incubator/kafka -``` - -### Connecting to Kafka from inside Kubernetes - -You can connect to Kafka by running a simple pod in the K8s cluster like this with a configuration like this: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: testclient - namespace: kafka -spec: - containers: - - name: kafka - image: solsson/kafka:0.11.0.0 - command: - - sh - - -c - - "exec tail -f /dev/null" -``` - -Once you have the testclient pod above running, you can list all kafka -topics with: - -` kubectl -n kafka exec -ti testclient -- ./bin/kafka-topics.sh --zookeeper -my-release-zookeeper:2181 --list` - -Where `my-release` is the name of your helm release. - -## Extensions - -Kafka has a rich ecosystem, with lots of tools. This sections is intended to compile all of those tools for which a corresponding Helm chart has already been created. - -- [Schema-registry](https://github.com/kubernetes/charts/tree/master/incubator/schema-registry) - A confluent project that provides a serving layer for your metadata. It provides a RESTful interface for storing and retrieving Avro schemas. - -## Connecting to Kafka from outside Kubernetes - -### NodePort External Service Type - -Review and optionally override to enable the example text concerned with external access in `values.yaml`. - -Once configured, you should be able to reach Kafka via NodePorts, one per replica. In kops where private, -topology is enabled, this feature publishes an internal round-robin DNS record using the following naming -scheme. The external access feature of this chart was tested with kops on AWS using flannel networking. -If you wish to enable external access to Kafka running in kops, your security groups will likely need to -be adjusted to allow non-Kubernetes nodes (e.g. bastion) to access the Kafka external listener port range. - -``` -{{ .Release.Name }}.{{ .Values.external.domain }} -``` - -If `external.distinct` is set theses entries will be prefixed with the replica number or broker id. - -``` -{{ .Release.Name }}-.{{ .Values.external.domain }} -``` - -Port numbers for external access used at container and NodePort are unique to each container in the StatefulSet. -Using the default `external.firstListenerPort` number with a `replicas` value of `3`, the following -container and NodePorts will be opened for external access: `31090`, `31091`, `31092`. All of these ports should -be reachable from any host to NodePorts are exposed because Kubernetes routes each NodePort from entry node -to pod/container listening on the same port (e.g. `31091`). - -The `external.servicePort` at each external access service (one such service per pod) is a relay toward -the a `containerPort` with a number matching its respective `NodePort`. The range of NodePorts is set, but -should not actually listen, on all Kafka pods in the StatefulSet. As any given pod will listen only one -such port at a time, setting the range at every Kafka pod is a reasonably safe configuration. - -#### Example values.yml for external service type NodePort -The + lines are with the updated values. -``` - external: -- enabled: false -+ enabled: true - # type can be either NodePort or LoadBalancer - type: NodePort - # annotations: -@@ -170,14 +170,14 @@ configurationOverrides: - ## - ## Setting "advertised.listeners" here appends to "PLAINTEXT://${POD_IP}:9092,", ensure you update the domain - ## If external service type is Nodeport: -- # "advertised.listeners": |- -- # EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) -+ "advertised.listeners": |- -+ EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) - ## If external service type is LoadBalancer and distinct is true: - # "advertised.listeners": |- - # EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).cluster.local:19092 - ## If external service type is LoadBalancer and distinct is false: - # "advertised.listeners": |- - # EXTERNAL://EXTERNAL://${LOAD_BALANCER_IP}:31090 - ## Uncomment to define the EXTERNAL Listener protocol -- # "listener.security.protocol.map": |- -- # PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT -+ "listener.security.protocol.map": |- -+ PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT - - -$ kafkacat -b kafka.cluster.local:31090 -L -Metadata for all topics (from broker 0: kafka.cluster.local:31090/0): - 3 brokers: - broker 2 at kafka.cluster.local:31092 - broker 1 at kafka.cluster.local:31091 - broker 0 at kafka.cluster.local:31090 - 0 topics: - -$ kafkacat -b kafka.cluster.local:31090 -P -t test1 -p 0 -msg01 from external producer to topic test1 - -$ kafkacat -b kafka.cluster.local:31090 -C -t test1 -p 0 -msg01 from external producer to topic test1 -``` -### LoadBalancer External Service Type - -The load balancer external service type differs from the node port type by routing to the `external.servicePort` specified in the service for each statefulset container (if `external.distinct` is set). If `external.distinct` is false, `external.servicePort` is unused and will be set to the sum of `external.firstListenerPort` and the replica number. It is important to note that `external.firstListenerPort` does not have to be within the configured node port range for the cluster, however a node port will be allocated. - -#### Example values.yml and DNS setup for external service type LoadBalancer with external.distinct: true -The + lines are with the updated values. -``` - external: -- enabled: false -+ enabled: true - # type can be either NodePort or LoadBalancer -- type: NodePort -+ type: LoadBalancer - # annotations: - # service.beta.kubernetes.io/openstack-internal-load-balancer: "true" - dns: -@@ -138,10 +138,10 @@ external: - # If using external service type LoadBalancer and external dns, set distinct to true below. - # This creates an A record for each statefulset pod/broker. You should then map the - # A record of the broker to the EXTERNAL IP given by the LoadBalancer in your DNS server. -- distinct: false -+ distinct: true - servicePort: 19092 - firstListenerPort: 31090 -- domain: cluster.local -+ domain: example.com - loadBalancerIP: [] - init: - image: "lwolf/kubectl_deployer" -@@ -173,11 +173,11 @@ configurationOverrides: - # "advertised.listeners": |- - # EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) - ## If external service type is LoadBalancer and distinct is true: -- # "advertised.listeners": |- -- # EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).cluster.local:19092 -+ "advertised.listeners": |- -+ EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).example.com:19092 - ## Uncomment to define the EXTERNAL Listener protocol -- # "listener.security.protocol.map": |- -- # PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT -+ "listener.security.protocol.map": |- -+ PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT - -$ kubectl -n kafka get svc -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -kafka ClusterIP 10.39.241.217 9092/TCP 2m39s -kafka-0-external LoadBalancer 10.39.242.45 35.200.238.174 19092:30108/TCP 2m39s -kafka-1-external LoadBalancer 10.39.241.90 35.244.44.162 19092:30582/TCP 2m39s -kafka-2-external LoadBalancer 10.39.243.160 35.200.149.80 19092:30539/TCP 2m39s -kafka-headless ClusterIP None 9092/TCP 2m39s -kafka-zookeeper ClusterIP 10.39.249.70 2181/TCP 2m39s -kafka-zookeeper-headless ClusterIP None 2181/TCP,3888/TCP,2888/TCP 2m39s - -DNS A record entries: -kafka-0.example.com A record 35.200.238.174 TTL 60sec -kafka-1.example.com A record 35.244.44.162 TTL 60sec -kafka-2.example.com A record 35.200.149.80 TTL 60sec - -$ ping kafka-0.example.com -PING kafka-0.example.com (35.200.238.174): 56 data bytes - -$ kafkacat -b kafka-0.example.com:19092 -L -Metadata for all topics (from broker 0: kafka-0.example.com:19092/0): - 3 brokers: - broker 2 at kafka-2.example.com:19092 - broker 1 at kafka-1.example.com:19092 - broker 0 at kafka-0.example.com:19092 - 0 topics: - -$ kafkacat -b kafka-0.example.com:19092 -P -t gkeTest -p 0 -msg02 for topic gkeTest - -$ kafkacat -b kafka-0.example.com:19092 -C -t gkeTest -p 0 -msg02 for topic gkeTest -``` - -#### Example values.yml and DNS setup for external service type LoadBalancer with external.distinct: false -The + lines are with the updated values. -``` - external: -- enabled: false -+ enabled: true - # type can be either NodePort or LoadBalancer -- type: NodePort -+ type: LoadBalancer - # annotations: - # service.beta.kubernetes.io/openstack-internal-load-balancer: "true" - dns: -@@ -138,10 +138,10 @@ external: - distinct: false - servicePort: 19092 - firstListenerPort: 31090 - domain: cluster.local - loadBalancerIP: [35.200.238.174,35.244.44.162,35.200.149.80] - init: - image: "lwolf/kubectl_deployer" -@@ -173,11 +173,11 @@ configurationOverrides: - # "advertised.listeners": |- - # EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) - ## If external service type is LoadBalancer and distinct is true: -- # "advertised.listeners": |- -- # EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).cluster.local:19092 -+ "advertised.listeners": |- -+ EXTERNAL://${LOAD_BALANCER_IP}:31090 - ## Uncomment to define the EXTERNAL Listener protocol -- # "listener.security.protocol.map": |- -- # PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT -+ "listener.security.protocol.map": |- -+ PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT - -$ kubectl -n kafka get svc -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -kafka ClusterIP 10.39.241.217 9092/TCP 2m39s -kafka-0-external LoadBalancer 10.39.242.45 35.200.238.174 31090:30108/TCP 2m39s -kafka-1-external LoadBalancer 10.39.241.90 35.244.44.162 31090:30582/TCP 2m39s -kafka-2-external LoadBalancer 10.39.243.160 35.200.149.80 31090:30539/TCP 2m39s -kafka-headless ClusterIP None 9092/TCP 2m39s -kafka-zookeeper ClusterIP 10.39.249.70 2181/TCP 2m39s -kafka-zookeeper-headless ClusterIP None 2181/TCP,3888/TCP,2888/TCP 2m39s - -$ kafkacat -b 35.200.238.174:31090 -L -Metadata for all topics (from broker 0: 35.200.238.174:31090/0): - 3 brokers: - broker 2 at 35.200.149.80:31090 - broker 1 at 35.244.44.162:31090 - broker 0 at 35.200.238.174:31090 - 0 topics: - -$ kafkacat -b 35.200.238.174:31090 -P -t gkeTest -p 0 -msg02 for topic gkeTest - -$ kafkacat -b 35.200.238.174:31090 -C -t gkeTest -p 0 -msg02 for topic gkeTest -``` - -## Known Limitations - -* Only supports storage options that have backends for persistent volume claims (tested mostly on AWS) -* KAFKA_PORT will be created as an envvar and brokers will fail to start when there is a service named `kafka` in the same namespace. We work around this be unsetting that envvar `unset KAFKA_PORT`. - -[brokerconfigs]: https://kafka.apache.org/documentation/#brokerconfigs - -## Prometheus Stats - -### Prometheus vs Prometheus Operator - -Standard Prometheus is the default monitoring option for this chart. This chart also supports the CoreOS Prometheus Operator, -which can provide additional functionality like automatically updating Prometheus and Alert Manager configuration. If you are -interested in installing the Prometheus Operator please see the [CoreOS repository](https://github.com/coreos/prometheus-operator/tree/master/helm) for more information or -read through the [CoreOS blog post introducing the Prometheus Operator](https://coreos.com/blog/the-prometheus-operator.html) - -### JMX Exporter - -The majority of Kafka statistics are provided via JMX and are exposed via the [Prometheus JMX Exporter](https://github.com/prometheus/jmx_exporter). - -The JMX Exporter is a general purpose prometheus provider which is intended for use with any Java application. Because of this, it produces a number of statistics which -may not be of interest. To help in reducing these statistics to their relevant components we have created a curated whitelist `whitelistObjectNames` for the JMX exporter. -This whitelist may be modified or removed via the values configuration. - -To accommodate compatibility with the Prometheus metrics, this chart performs transformations of raw JMX metrics. For example, broker names and topics names are incorporated -into the metric name instead of becoming a label. If you are curious to learn more about any default transformations to the chart metrics, please have reference the [configmap template](https://github.com/kubernetes/charts/blob/master/incubator/kafka/templates/jmx-configmap.yaml). - -### Kafka Exporter - -The [Kafka Exporter](https://github.com/danielqsj/kafka_exporter) is a complementary metrics exporter to the JMX Exporter. The Kafka Exporter provides additional statistics on Kafka Consumer Groups. diff --git a/infra/charts/feast/charts/kafka/charts/zookeeper-2.1.0.tgz b/infra/charts/feast/charts/kafka/charts/zookeeper-2.1.0.tgz deleted file mode 100644 index 76d35b5ea7eb1fd642475efb471d14439069a579..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10646 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 diff --git a/infra/charts/feast/charts/kafka/requirements.lock b/infra/charts/feast/charts/kafka/requirements.lock deleted file mode 100644 index 2df3aa8437e..00000000000 --- a/infra/charts/feast/charts/kafka/requirements.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: zookeeper - repository: https://kubernetes-charts-incubator.storage.googleapis.com/ - version: 2.1.0 -digest: sha256:f50b0b5f50f4938a5369c5ea479030a4f87e99aecb7752ab434f75a6c39f304a -generated: "2019-11-05T16:37:25.868424523-06:00" diff --git a/infra/charts/feast/charts/kafka/requirements.yaml b/infra/charts/feast/charts/kafka/requirements.yaml deleted file mode 100644 index 4d2a03f4cba..00000000000 --- a/infra/charts/feast/charts/kafka/requirements.yaml +++ /dev/null @@ -1,5 +0,0 @@ -dependencies: -- name: zookeeper - version: 2.1.0 - repository: https://kubernetes-charts-incubator.storage.googleapis.com/ - condition: kafka.zookeeper.enabled,zookeeper.enabled diff --git a/infra/charts/feast/charts/kafka/templates/NOTES.txt b/infra/charts/feast/charts/kafka/templates/NOTES.txt deleted file mode 100644 index fb35027a115..00000000000 --- a/infra/charts/feast/charts/kafka/templates/NOTES.txt +++ /dev/null @@ -1,76 +0,0 @@ -### Connecting to Kafka from inside Kubernetes - -You can connect to Kafka by running a simple pod in the K8s cluster like this with a configuration like this: - - apiVersion: v1 - kind: Pod - metadata: - name: testclient - namespace: {{ .Release.Namespace }} - spec: - containers: - - name: kafka - image: {{ .Values.image }}:{{ .Values.imageTag }} - command: - - sh - - -c - - "exec tail -f /dev/null" - -Once you have the testclient pod above running, you can list all kafka -topics with: - - kubectl -n {{ .Release.Namespace }} exec testclient -- kafka-topics --zookeeper {{ .Release.Name }}-zookeeper:2181 --list - -To create a new topic: - - kubectl -n {{ .Release.Namespace }} exec testclient -- kafka-topics --zookeeper {{ .Release.Name }}-zookeeper:2181 --topic test1 --create --partitions 1 --replication-factor 1 - -To listen for messages on a topic: - - kubectl -n {{ .Release.Namespace }} exec -ti testclient -- kafka-console-consumer --bootstrap-server {{ include "kafka.fullname" . }}:9092 --topic test1 --from-beginning - -To stop the listener session above press: Ctrl+C - -To start an interactive message producer session: - kubectl -n {{ .Release.Namespace }} exec -ti testclient -- kafka-console-producer --broker-list {{ include "kafka.fullname" . }}-headless:9092 --topic test1 - -To create a message in the above session, simply type the message and press "enter" -To end the producer session try: Ctrl+C - -If you specify "zookeeper.connect" in configurationOverrides, please replace "{{ .Release.Name }}-zookeeper:2181" with the value of "zookeeper.connect", or you will get error. - -{{ if .Values.external.enabled }} -### Connecting to Kafka from outside Kubernetes - -You have enabled the external access feature of this chart. - -**WARNING:** By default this feature allows Kafka clients outside Kubernetes to -connect to Kafka via NodePort(s) in `PLAINTEXT`. - -Please see this chart's README.md for more details and guidance. - -If you wish to connect to Kafka from outside please configure your external Kafka -clients to point at the following brokers. Please allow a few minutes for all -associated resources to become healthy. - {{ $fullName := include "kafka.fullname" . }} - {{- $replicas := .Values.replicas | int }} - {{- $servicePort := .Values.external.servicePort | int}} - {{- $root := . }} - {{- range $i, $e := until $replicas }} - {{- $externalListenerPort := add $root.Values.external.firstListenerPort $i }} - {{- if $root.Values.external.distinct }} -{{ printf "%s-%d.%s:%d" $root.Release.Name $i $root.Values.external.domain $servicePort | indent 2 }} - {{- else }} -{{ printf "%s.%s:%d" $root.Release.Name $root.Values.external.domain $externalListenerPort | indent 2 }} - {{- end }} - {{- end }} -{{- end }} - -{{ if .Values.prometheus.jmx.enabled }} -To view JMX configuration (pull request/updates to improve defaults are encouraged): - {{ if .Values.jmx.configMap.overrideName }} - kubectl -n {{ .Release.Namespace }} describe configmap {{ .Values.jmx.configMap.overrideName }} - {{ else }} - kubectl -n {{ .Release.Namespace }} describe configmap {{ include "kafka.fullname" . }}-metrics - {{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/_helpers.tpl b/infra/charts/feast/charts/kafka/templates/_helpers.tpl deleted file mode 100644 index 03bfc0ace43..00000000000 --- a/infra/charts/feast/charts/kafka/templates/_helpers.tpl +++ /dev/null @@ -1,128 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "kafka.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 "kafka.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create a default fully qualified zookeeper name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "kafka.zookeeper.fullname" -}} -{{- if .Values.zookeeper.fullnameOverride -}} -{{- .Values.zookeeper.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default "zookeeper" .Values.zookeeper.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} - -{{/* -Form the Zookeeper URL. If zookeeper is installed as part of this chart, use k8s service discovery, -else use user-provided URL -*/}} -{{- define "zookeeper.url" }} -{{- $port := .Values.zookeeper.port | toString }} -{{- if .Values.zookeeper.enabled -}} -{{- printf "%s:%s" (include "kafka.zookeeper.fullname" .) $port }} -{{- else -}} -{{- $zookeeperConnect := printf "%s:%s" .Values.zookeeper.url $port }} -{{- $zookeeperConnectOverride := index .Values "configurationOverrides" "zookeeper.connect" }} -{{- default $zookeeperConnect $zookeeperConnectOverride }} -{{- end -}} -{{- end -}} - -{{/* -Derive offsets.topic.replication.factor in following priority order: configurationOverrides, replicas -*/}} -{{- define "kafka.replication.factor" }} -{{- $replicationFactorOverride := index .Values "configurationOverrides" "offsets.topic.replication.factor" }} -{{- default .Values.replicas $replicationFactorOverride }} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "kafka.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create unified labels for kafka components -*/}} - -{{- define "kafka.common.matchLabels" -}} -app.kubernetes.io/name: {{ include "kafka.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end -}} - -{{- define "kafka.common.metaLabels" -}} -helm.sh/chart: {{ include "kafka.chart" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end -}} - -{{- define "kafka.broker.matchLabels" -}} -app.kubernetes.io/component: kafka-broker -{{ include "kafka.common.matchLabels" . }} -{{- end -}} - -{{- define "kafka.broker.labels" -}} -{{ include "kafka.common.metaLabels" . }} -{{ include "kafka.broker.matchLabels" . }} -{{- end -}} - -{{- define "kafka.config.matchLabels" -}} -app.kubernetes.io/component: kafka-config -{{ include "kafka.common.matchLabels" . }} -{{- end -}} - -{{- define "kafka.config.labels" -}} -{{ include "kafka.common.metaLabels" . }} -{{ include "kafka.config.matchLabels" . }} -{{- end -}} - -{{- define "kafka.monitor.matchLabels" -}} -app.kubernetes.io/component: kafka-monitor -{{ include "kafka.common.matchLabels" . }} -{{- end -}} - -{{- define "kafka.monitor.labels" -}} -{{ include "kafka.common.metaLabels" . }} -{{ include "kafka.monitor.matchLabels" . }} -{{- end -}} - -{{- define "serviceMonitor.namespace" -}} -{{- if .Values.prometheus.operator.serviceMonitor.releaseNamespace -}} -{{ .Release.Namespace }} -{{- else -}} -{{ .Values.prometheus.operator.serviceMonitor.namespace }} -{{- end -}} -{{- end -}} - -{{- define "prometheusRule.namespace" -}} -{{- if .Values.prometheus.operator.prometheusRule.releaseNamespace -}} -{{ .Release.Namespace }} -{{- else -}} -{{ .Values.prometheus.operator.prometheusRule.namespace }} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/kafka/templates/configmap-config.yaml b/infra/charts/feast/charts/kafka/templates/configmap-config.yaml deleted file mode 100644 index 020c8b55590..00000000000 --- a/infra/charts/feast/charts/kafka/templates/configmap-config.yaml +++ /dev/null @@ -1,58 +0,0 @@ -{{- if .Values.topics -}} -{{- $zk := include "zookeeper.url" . -}} -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - {{- include "kafka.config.labels" . | nindent 4 }} - name: {{ template "kafka.fullname" . }}-config -data: - runtimeConfig.sh: | - #!/bin/bash - set -e - cd /usr/bin - until kafka-configs --zookeeper {{ $zk }} --entity-type topics --describe || (( count++ >= 6 )) - do - echo "Waiting for Zookeeper..." - sleep 20 - done - until nc -z {{ template "kafka.fullname" . }} 9092 || (( retries++ >= 6 )) - do - echo "Waiting for Kafka..." - sleep 20 - done - echo "Applying runtime configuration using {{ .Values.image }}:{{ .Values.imageTag }}" - {{- range $n, $topic := .Values.topics }} - {{- if and $topic.partitions $topic.replicationFactor $topic.reassignPartitions }} - cat << EOF > {{ $topic.name }}-increase-replication-factor.json - {"version":1, "partitions":[ - {{- $partitions := (int $topic.partitions) }} - {{- $replicas := (int $topic.replicationFactor) }} - {{- range $i := until $partitions }} - {"topic":"{{ $topic.name }}","partition":{{ $i }},"replicas":[{{- range $j := until $replicas }}{{ $j }}{{- if ne $j (sub $replicas 1) }},{{- end }}{{- end }}]}{{- if ne $i (sub $partitions 1) }},{{- end }} - {{- end }} - ]} - EOF - kafka-reassign-partitions --zookeeper {{ $zk }} --reassignment-json-file {{ $topic.name }}-increase-replication-factor.json --execute - kafka-reassign-partitions --zookeeper {{ $zk }} --reassignment-json-file {{ $topic.name }}-increase-replication-factor.json --verify - {{- else if and $topic.partitions $topic.replicationFactor }} - kafka-topics --zookeeper {{ $zk }} --create --if-not-exists --force --topic {{ $topic.name }} --partitions {{ $topic.partitions }} --replication-factor {{ $topic.replicationFactor }} - {{- else if $topic.partitions }} - kafka-topics --zookeeper {{ $zk }} --alter --force --topic {{ $topic.name }} --partitions {{ $topic.partitions }} || true - {{- end }} - {{- if $topic.defaultConfig }} - kafka-configs --zookeeper {{ $zk }} --entity-type topics --entity-name {{ $topic.name }} --alter --force --delete-config {{ nospace $topic.defaultConfig }} || true - {{- end }} - {{- if $topic.config }} - kafka-configs --zookeeper {{ $zk }} --entity-type topics --entity-name {{ $topic.name }} --alter --force --add-config {{ nospace $topic.config }} - {{- end }} - kafka-configs --zookeeper {{ $zk }} --entity-type topics --entity-name {{ $topic.name }} --describe - {{- if $topic.acls }} - {{- range $a, $acl := $topic.acls }} - {{ if and $acl.user $acl.operations }} - kafka-acls --authorizer-properties zookeeper.connect={{ $zk }} --force --add --allow-principal User:{{ $acl.user }}{{- range $operation := $acl.operations }} --operation {{ $operation }} {{- end }} --topic {{ $topic.name }} {{ $topic.extraParams }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} -{{- end -}} diff --git a/infra/charts/feast/charts/kafka/templates/configmap-jmx.yaml b/infra/charts/feast/charts/kafka/templates/configmap-jmx.yaml deleted file mode 100644 index 9eae92106ab..00000000000 --- a/infra/charts/feast/charts/kafka/templates/configmap-jmx.yaml +++ /dev/null @@ -1,64 +0,0 @@ -{{- if and .Values.prometheus.jmx.enabled .Values.jmx.configMap.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "kafka.fullname" . }}-metrics - labels: - {{- include "kafka.monitor.labels" . | nindent 4 }} -data: - jmx-kafka-prometheus.yml: |+ -{{- if .Values.jmx.configMap.overrideConfig }} -{{ toYaml .Values.jmx.configMap.overrideConfig | indent 4 }} -{{- else }} - jmxUrl: service:jmx:rmi:///jndi/rmi://127.0.0.1:{{ .Values.jmx.port }}/jmxrmi - lowercaseOutputName: true - lowercaseOutputLabelNames: true - ssl: false - {{ if .Values.jmx.whitelistObjectNames }} - whitelistObjectNames: ["{{ join "\",\"" .Values.jmx.whitelistObjectNames }}"] - {{ end }} - rules: - - pattern: kafka.controller<>(Value) - name: kafka_controller_$1_$2_$4 - labels: - broker_id: "$3" - - pattern: kafka.controller<>(Value) - name: kafka_controller_$1_$2_$3 - - pattern: kafka.controller<>(Value) - name: kafka_controller_$1_$2_$3 - - pattern: kafka.controller<>(Count) - name: kafka_controller_$1_$2_$3 - - pattern: kafka.server<>(Value) - name: kafka_server_$1_$2_$4 - labels: - client_id: "$3" - - pattern : kafka.network<>(Value) - name: kafka_network_$1_$2_$4 - labels: - network_processor: $3 - - pattern : kafka.network<>(Count) - name: kafka_network_$1_$2_$4 - labels: - request: $3 - - pattern: kafka.server<>(Count|OneMinuteRate) - name: kafka_server_$1_$2_$4 - labels: - topic: $3 - - pattern: kafka.server<>(Value) - name: kafka_server_$1_$2_$3_$4 - - pattern: kafka.server<>(Count|Value|OneMinuteRate) - name: kafka_server_$1_total_$2_$3 - - pattern: kafka.server<>(queue-size) - name: kafka_server_$1_$2 - - pattern: java.lang<(.+)>(\w+) - name: java_lang_$1_$4_$3_$2 - - pattern: java.lang<>(\w+) - name: java_lang_$1_$3_$2 - - pattern : java.lang - - pattern: kafka.log<>Value - name: kafka_log_$1_$2 - labels: - topic: $3 - partition: $4 -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/deployment-kafka-exporter.yaml b/infra/charts/feast/charts/kafka/templates/deployment-kafka-exporter.yaml deleted file mode 100644 index 85e5a605b72..00000000000 --- a/infra/charts/feast/charts/kafka/templates/deployment-kafka-exporter.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- if .Values.prometheus.kafka.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "kafka.fullname" . }}-exporter - labels: - {{- include "kafka.monitor.labels" . | nindent 4 }} -spec: - replicas: 1 - selector: - matchLabels: - {{- include "kafka.monitor.matchLabels" . | nindent 6 }} - template: - metadata: - annotations: -{{- if and .Values.prometheus.kafka.enabled (not .Values.prometheus.operator.enabled) }} - prometheus.io/scrape: "true" - prometheus.io/port: {{ .Values.prometheus.kafka.port | quote }} -{{- end }} - labels: - {{- include "kafka.monitor.labels" . | nindent 8 }} - spec: - containers: - - image: "{{ .Values.prometheus.kafka.image }}:{{ .Values.prometheus.kafka.imageTag }}" - name: kafka-exporter - args: - - --kafka.server={{ template "kafka.fullname" . }}:9092 - - --web.listen-address=:{{ .Values.prometheus.kafka.port }} - ports: - - containerPort: {{ .Values.prometheus.kafka.port }} - resources: -{{ toYaml .Values.prometheus.kafka.resources | indent 10 }} -{{- if .Values.prometheus.kafka.tolerations }} - tolerations: -{{ toYaml .Values.prometheus.kafka.tolerations | indent 8 }} -{{- end }} -{{- if .Values.prometheus.kafka.affinity }} - affinity: -{{ toYaml .Values.prometheus.kafka.affinity | indent 8 }} -{{- end }} -{{- if .Values.prometheus.kafka.nodeSelector }} - nodeSelector: -{{ toYaml .Values.prometheus.kafka.nodeSelector | indent 8 }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/job-config.yaml b/infra/charts/feast/charts/kafka/templates/job-config.yaml deleted file mode 100644 index 13576b3fef0..00000000000 --- a/infra/charts/feast/charts/kafka/templates/job-config.yaml +++ /dev/null @@ -1,29 +0,0 @@ -{{- if .Values.topics -}} -{{- $scriptHash := include (print $.Template.BasePath "/configmap-config.yaml") . | sha256sum | trunc 8 -}} -apiVersion: batch/v1 -kind: Job -metadata: - name: "{{ template "kafka.fullname" . }}-config-{{ $scriptHash }}" - labels: - {{- include "kafka.config.labels" . | nindent 4 }} -spec: - backoffLimit: {{ .Values.configJob.backoffLimit }} - template: - metadata: - labels: - {{- include "kafka.config.matchLabels" . | nindent 8 }} - spec: - restartPolicy: OnFailure - volumes: - - name: config-volume - configMap: - name: {{ template "kafka.fullname" . }}-config - defaultMode: 0744 - containers: - - name: {{ template "kafka.fullname" . }}-config - image: "{{ .Values.image }}:{{ .Values.imageTag }}" - command: ["/usr/local/script/runtimeConfig.sh"] - volumeMounts: - - name: config-volume - mountPath: "/usr/local/script" -{{- end -}} diff --git a/infra/charts/feast/charts/kafka/templates/podisruptionbudget.yaml b/infra/charts/feast/charts/kafka/templates/podisruptionbudget.yaml deleted file mode 100644 index 7e1c03f9fae..00000000000 --- a/infra/charts/feast/charts/kafka/templates/podisruptionbudget.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if .Values.podDisruptionBudget }} -apiVersion: policy/v1beta1 -kind: PodDisruptionBudget -metadata: - name: {{ include "kafka.fullname" . }} - labels: - {{- include "kafka.broker.labels" . | nindent 4 }} -spec: - selector: - matchLabels: - {{- include "kafka.broker.matchLabels" . | nindent 6 }} -{{ toYaml .Values.podDisruptionBudget | indent 2 }} - -{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/prometheusrules.yaml b/infra/charts/feast/charts/kafka/templates/prometheusrules.yaml deleted file mode 100644 index 4f74ad5d050..00000000000 --- a/infra/charts/feast/charts/kafka/templates/prometheusrules.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{ if and .Values.prometheus.operator.enabled .Values.prometheus.operator.prometheusRule.enabled .Values.prometheus.operator.prometheusRule.rules }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ include "kafka.fullname" . }} - namespace: {{ include "serviceMonitor.namespace" . }} - labels: - {{- include "kafka.monitor.labels" . | nindent 4 }} - {{- toYaml .Values.prometheus.operator.prometheusRule.selector | nindent 4 }} -spec: - groups: - - name: {{ include "kafka.fullname" . }} - rules: - {{- toYaml .Values.prometheus.operator.prometheusRule.rules | nindent 6 }} -{{- end }} - diff --git a/infra/charts/feast/charts/kafka/templates/service-brokers-external.yaml b/infra/charts/feast/charts/kafka/templates/service-brokers-external.yaml deleted file mode 100644 index 3d35a8e3ff1..00000000000 --- a/infra/charts/feast/charts/kafka/templates/service-brokers-external.yaml +++ /dev/null @@ -1,74 +0,0 @@ -{{- if .Values.external.enabled }} - {{- $fullName := include "kafka.fullname" . }} - {{- $replicas := .Values.replicas | int }} - {{- $servicePort := .Values.external.servicePort }} - {{- $firstListenerPort := .Values.external.firstListenerPort }} - {{- $dnsPrefix := printf "%s" .Release.Name }} - {{- $root := . }} - {{- range $i, $e := until $replicas }} - {{- $externalListenerPort := add $root.Values.external.firstListenerPort $i }} - {{- $responsiblePod := printf "%s-%d" (printf "%s" $fullName) $i }} - {{- $distinctPrefix := printf "%s-%d" $dnsPrefix $i }} - {{- $loadBalancerIPLen := len $root.Values.external.loadBalancerIP }} - ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - {{- if $root.Values.external.distinct }} - {{- if $root.Values.external.dns.useInternal }} - dns.alpha.kubernetes.io/internal: "{{ $distinctPrefix }}.{{ $root.Values.external.domain }}" - {{- end }} - {{- if $root.Values.external.dns.useExternal }} - external-dns.alpha.kubernetes.io/hostname: "{{ $distinctPrefix }}.{{ $root.Values.external.domain }}" - {{- end }} - {{- else }} - {{- if $root.Values.external.dns.useInternal }} - dns.alpha.kubernetes.io/internal: "{{ $dnsPrefix }}.{{ $root.Values.external.domain }}" - {{- end }} - {{- if $root.Values.external.dns.useExternal }} - external-dns.alpha.kubernetes.io/hostname: "{{ $dnsPrefix }}.{{ $root.Values.external.domain }}" - {{- end }} - {{- end }} - {{- if $root.Values.external.annotations }} -{{ toYaml $root.Values.external.annotations | indent 4 }} - {{- end }} - name: {{ $root.Release.Name }}-{{ $i }}-external - labels: - {{- include "kafka.broker.labels" $root | nindent 4 }} - pod: {{ $responsiblePod | quote }} -spec: - type: {{ $root.Values.external.type }} - ports: - - name: external-broker - {{- if and (eq $root.Values.external.type "LoadBalancer") (not $root.Values.external.distinct) }} - port: {{ $firstListenerPort }} - {{- else }} - port: {{ $servicePort }} - {{- end }} - {{- if and (eq $root.Values.external.type "LoadBalancer") ($root.Values.external.distinct) }} - targetPort: {{ $servicePort }} - {{- else if and (eq $root.Values.external.type "LoadBalancer") (not $root.Values.external.distinct) }} - targetPort: {{ $firstListenerPort }} - {{- else }} - targetPort: {{ $externalListenerPort }} - {{- end }} - {{- if eq $root.Values.external.type "NodePort" }} - nodePort: {{ $externalListenerPort }} - {{- end }} - protocol: TCP - {{- if and (eq $root.Values.external.type "LoadBalancer") (eq $loadBalancerIPLen $replicas) }} - loadBalancerIP: {{ index $root.Values.external.loadBalancerIP $i }} - {{- end }} - {{- if $root.Values.external.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $root.Values.external.loadBalancerSourceRanges }} - - {{ . | quote}} - {{- end }} - {{- end }} - selector: - {{- include "kafka.broker.matchLabels" $root | nindent 4 }} - statefulset.kubernetes.io/pod-name: {{ $responsiblePod | quote }} - {{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/service-brokers.yaml b/infra/charts/feast/charts/kafka/templates/service-brokers.yaml deleted file mode 100644 index 744843e1b71..00000000000 --- a/infra/charts/feast/charts/kafka/templates/service-brokers.yaml +++ /dev/null @@ -1,36 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "kafka.fullname" . }} - labels: - {{- include "kafka.broker.labels" . | nindent 4 }} -spec: - ports: - - name: broker - port: 9092 - targetPort: kafka -{{- if and .Values.prometheus.jmx.enabled .Values.prometheus.operator.enabled }} - - name: jmx-exporter - protocol: TCP - port: {{ .Values.jmx.port }} - targetPort: prometheus -{{- end }} - selector: - {{- include "kafka.broker.matchLabels" . | nindent 4 }} ---- -{{- if and .Values.prometheus.kafka.enabled .Values.prometheus.operator.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "kafka.fullname" . }}-exporter - labels: - {{- include "kafka.monitor.labels" . | nindent 4 }} -spec: - ports: - - name: kafka-exporter - protocol: TCP - port: {{ .Values.prometheus.kafka.port }} - targetPort: {{ .Values.prometheus.kafka.port }} - selector: - {{- include "kafka.monitor.matchLabels" . | nindent 4 }} -{{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/service-headless.yaml b/infra/charts/feast/charts/kafka/templates/service-headless.yaml deleted file mode 100644 index 2fa7cf7763a..00000000000 --- a/infra/charts/feast/charts/kafka/templates/service-headless.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "kafka.fullname" . }}-headless - labels: - {{- include "kafka.broker.labels" . | nindent 4 }} - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" -{{- if .Values.headless.annotations }} -{{ .Values.headless.annotations | toYaml | trimSuffix "\n" | indent 4 }} -{{- end }} -spec: - ports: - - name: broker - port: {{ .Values.headless.port }} -{{- if .Values.headless.targetPort }} - targetPort: {{ .Values.headless.targetPort }} -{{- end }} - clusterIP: None - selector: - {{- include "kafka.broker.matchLabels" . | nindent 4 }} diff --git a/infra/charts/feast/charts/kafka/templates/servicemonitors.yaml b/infra/charts/feast/charts/kafka/templates/servicemonitors.yaml deleted file mode 100644 index 6d35feb71c5..00000000000 --- a/infra/charts/feast/charts/kafka/templates/servicemonitors.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{ if and .Values.prometheus.jmx.enabled .Values.prometheus.operator.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ include "kafka.fullname" . }} - namespace: {{ include "serviceMonitor.namespace" . }} - labels: - {{- include "kafka.monitor.labels" . | nindent 4 }} - {{- toYaml .Values.prometheus.operator.serviceMonitor.selector | nindent 4 }} -spec: - selector: - matchLabels: - {{- include "kafka.broker.matchLabels" . | nindent 6 }} - endpoints: - - port: jmx-exporter - interval: {{ .Values.prometheus.jmx.interval }} - {{- if .Values.prometheus.jmx.scrapeTimeout }} - scrapeTimeout: {{ .Values.prometheus.jmx.scrapeTimeout }} - {{- end }} - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} -{{ end }} ---- -{{ if and .Values.prometheus.kafka.enabled .Values.prometheus.operator.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ include "kafka.fullname" . }}-exporter - namespace: {{ include "serviceMonitor.namespace" . }} - labels: - {{- include "kafka.monitor.labels" . | nindent 4 }} - {{ toYaml .Values.prometheus.operator.serviceMonitor.selector | nindent 4 }} -spec: - selector: - matchLabels: - {{- include "kafka.monitor.matchLabels" . | nindent 6 }} - endpoints: - - port: kafka-exporter - interval: {{ .Values.prometheus.kafka.interval }} - {{- if .Values.prometheus.kafka.scrapeTimeout }} - scrapeTimeout: {{ .Values.prometheus.kafka.scrapeTimeout }} - {{- end }} - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} -{{ end }} diff --git a/infra/charts/feast/charts/kafka/templates/statefulset.yaml b/infra/charts/feast/charts/kafka/templates/statefulset.yaml deleted file mode 100644 index 5e056ece1c2..00000000000 --- a/infra/charts/feast/charts/kafka/templates/statefulset.yaml +++ /dev/null @@ -1,272 +0,0 @@ -{{- $advertisedListenersOverride := first (pluck "advertised.listeners" .Values.configurationOverrides) }} -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ include "kafka.fullname" . }} - labels: - {{- include "kafka.broker.labels" . | nindent 4 }} -spec: - selector: - matchLabels: - {{- include "kafka.broker.matchLabels" . | nindent 6 }} - serviceName: {{ include "kafka.fullname" . }}-headless - podManagementPolicy: {{ .Values.podManagementPolicy }} - updateStrategy: -{{ toYaml .Values.updateStrategy | indent 4 }} - replicas: {{ default 3 .Values.replicas }} - template: - metadata: -{{- if or .Values.podAnnotations (and .Values.prometheus.jmx.enabled (not .Values.prometheus.operator.enabled)) }} - annotations: -{{- if and .Values.prometheus.jmx.enabled (not .Values.prometheus.operator.enabled) }} - prometheus.io/scrape: "true" - prometheus.io/port: {{ .Values.prometheus.jmx.port | quote }} -{{- end }} -{{- if .Values.podAnnotations }} -{{ toYaml .Values.podAnnotations | indent 8 }} -{{- end }} -{{- end }} - labels: - {{- include "kafka.broker.labels" . | nindent 8 }} - {{- if .Values.podLabels }} - ## Custom pod labels -{{ toYaml .Values.podLabels | indent 8 }} - {{- end }} - spec: -{{- if .Values.schedulerName }} - schedulerName: "{{ .Values.schedulerName }}" -{{- end }} -{{- if .Values.serviceAccountName }} - serviceAccountName: {{ .Values.serviceAccountName }} -{{- end }} -{{- if .Values.priorityClassName }} - priorityClassName: "{{ .Values.priorityClassName }}" -{{- end }} -{{- if .Values.tolerations }} - tolerations: -{{ toYaml .Values.tolerations | indent 8 }} -{{- end }} -{{- if .Values.affinity }} - affinity: -{{ toYaml .Values.affinity | indent 8 }} -{{- end }} -{{- if .Values.nodeSelector }} - nodeSelector: -{{ toYaml .Values.nodeSelector | indent 8 }} -{{- end }} - containers: - {{- if .Values.prometheus.jmx.enabled }} - - name: metrics - image: "{{ .Values.prometheus.jmx.image }}:{{ .Values.prometheus.jmx.imageTag }}" - command: - - sh - - -exc - - | - trap "exit 0" TERM; \ - while :; do \ - java \ - -XX:+UnlockExperimentalVMOptions \ - -XX:+UseCGroupMemoryLimitForHeap \ - -XX:MaxRAMFraction=1 \ - -XshowSettings:vm \ - -jar \ - jmx_prometheus_httpserver.jar \ - {{ .Values.prometheus.jmx.port | quote }} \ - /etc/jmx-kafka/jmx-kafka-prometheus.yml & \ - wait $! || sleep 3; \ - done - ports: - - containerPort: {{ .Values.prometheus.jmx.port }} - name: prometheus - resources: -{{ toYaml .Values.prometheus.jmx.resources | indent 10 }} - volumeMounts: - - name: jmx-config - mountPath: /etc/jmx-kafka - {{- end }} - - name: {{ include "kafka.name" . }}-broker - image: "{{ .Values.image }}:{{ .Values.imageTag }}" - imagePullPolicy: "{{ .Values.imagePullPolicy }}" - livenessProbe: - exec: - command: - - sh - - -ec - - /usr/bin/jps | /bin/grep -q SupportedKafka - {{- if not .Values.livenessProbe }} - initialDelaySeconds: 30 - timeoutSeconds: 5 - {{- else }} - initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds | default 30}} - {{- if .Values.livenessProbe.periodSeconds }} - periodSeconds: {{ .Values.livenessProbe.periodSeconds }} - {{- end }} - timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds | default 5}} - {{- if .Values.livenessProbe.successThreshold }} - successThreshold: {{ .Values.livenessProbe.successThreshold }} - {{- end }} - {{- if .Values.livenessProbe.failureThreshold }} - failureThreshold: {{ .Values.livenessProbe.failureThreshold }} - {{- end }} - {{- end }} - readinessProbe: - tcpSocket: - port: kafka - initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.readinessProbe.failureThreshold }} - ports: - - containerPort: 9092 - name: kafka - {{- if .Values.external.enabled }} - {{- $replicas := .Values.replicas | int }} - {{- $root := . }} - {{- range $i, $e := until $replicas }} - - containerPort: {{ add $root.Values.external.firstListenerPort $i }} - name: external-{{ $i }} - {{- end }} - {{- end }} - {{- if .Values.prometheus.jmx.enabled }} - - containerPort: {{ .Values.jmx.port }} - name: jmx - {{- end }} - {{- if .Values.additionalPorts }} -{{ toYaml .Values.additionalPorts | indent 8 }} - {{- end }} - resources: -{{ toYaml .Values.resources | indent 10 }} - env: - {{- if .Values.prometheus.jmx.enabled }} - - name: JMX_PORT - value: "{{ .Values.jmx.port }}" - {{- end }} - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: KAFKA_HEAP_OPTS - value: {{ .Values.kafkaHeapOptions }} - - name: KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR - value: {{ include "kafka.replication.factor" . | quote }} - {{- if not (hasKey .Values.configurationOverrides "zookeeper.connect") }} - - name: KAFKA_ZOOKEEPER_CONNECT - value: {{ include "zookeeper.url" . | quote }} - {{- end }} - {{- if not (hasKey .Values.configurationOverrides "log.dirs") }} - - name: KAFKA_LOG_DIRS - value: {{ printf "%s/%s" .Values.persistence.mountPath .Values.logSubPath | quote }} - {{- end }} - {{- range $key, $value := .Values.configurationOverrides }} - - name: {{ printf "KAFKA_%s" $key | replace "." "_" | upper | quote }} - value: {{ $value | quote }} - {{- end }} - {{- if .Values.jmx.port }} - - name: KAFKA_JMX_PORT - value: "{{ .Values.jmx.port }}" - {{- end }} - {{- range $secret := .Values.secrets }} - {{- if not $secret.mountPath }} - {{- range $key := $secret.keys }} - - name: {{ (print ($secret.name | replace "-" "_") "_" $key) | upper }} - valueFrom: - secretKeyRef: - name: {{ $secret.name }} - key: {{ $key }} - {{- end }} - {{- end }} - {{- end }} - {{- range $key, $value := .Values.envOverrides }} - - name: {{ printf "%s" $key | replace "." "_" | upper | quote }} - value: {{ $value | quote }} - {{- end }} - # This is required because the Downward API does not yet support identification of - # pod numbering in statefulsets. Thus, we are required to specify a command which - # allows us to extract the pod ID for usage as the Kafka Broker ID. - # See: https://github.com/kubernetes/kubernetes/issues/31218 - command: - - sh - - -exc - - | - unset KAFKA_PORT && \ - export KAFKA_BROKER_ID=${POD_NAME##*-} && \ - {{- if eq .Values.external.type "LoadBalancer" }} - export LOAD_BALANCER_IP=$(echo '{{ .Values.external.loadBalancerIP }}' | tr -d '[]' | cut -d ' ' -f "$(($KAFKA_BROKER_ID + 1))") && \ - {{- end }} - {{- if eq .Values.external.type "NodePort" }} - export KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${POD_IP}:9092{{ if kindIs "string" $advertisedListenersOverride }}{{ printf ",%s" $advertisedListenersOverride }}{{ end }} && \ - {{- else }} - export KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${POD_NAME}.{{ include "kafka.fullname" . }}-headless.${POD_NAMESPACE}.svc.cluster.local:9092{{ if kindIs "string" $advertisedListenersOverride }}{{ printf ",%s" $advertisedListenersOverride }}{{ end }} && \ - {{- end }} - exec /etc/confluent/docker/run - volumeMounts: - - name: datadir - mountPath: {{ .Values.persistence.mountPath | quote }} - {{- range $secret := .Values.secrets }} - {{- if $secret.mountPath }} - {{- if $secret.keys }} - {{- range $key := $secret.keys }} - - name: {{ include "kafka.fullname" $ }}-{{ $secret.name }} - mountPath: {{ $secret.mountPath }}/{{ $key }} - subPath: {{ $key }} - readOnly: true - {{- end }} - {{- else }} - - name: {{ include "kafka.fullname" $ }}-{{ $secret.name }} - mountPath: {{ $secret.mountPath }} - readOnly: true - {{- end }} - {{- end }} - {{- end }} - volumes: - {{- if not .Values.persistence.enabled }} - - name: datadir - emptyDir: {} - {{- end }} - {{- if .Values.prometheus.jmx.enabled }} - - name: jmx-config - configMap: - {{- if .Values.jmx.configMap.overrideName }} - name: {{ .Values.jmx.configMap.overrideName }} - {{- else }} - name: {{ include "kafka.fullname" . }}-metrics - {{- end }} - {{- end }} - {{- if .Values.securityContext }} - securityContext: -{{ toYaml .Values.securityContext | indent 8 }} - {{- end }} - {{- range .Values.secrets }} - {{- if .mountPath }} - - name: {{ include "kafka.fullname" $ }}-{{ .name }} - secret: - secretName: {{ .name }} - {{- end }} - {{- end }} - terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} - {{- if .Values.persistence.enabled }} - volumeClaimTemplates: - - metadata: - name: datadir - spec: - accessModes: [ "ReadWriteOnce" ] - resources: - requests: - storage: {{ .Values.persistence.size }} - {{- if .Values.persistence.storageClass }} - {{- if (eq "-" .Values.persistence.storageClass) }} - storageClassName: "" - {{- else }} - storageClassName: "{{ .Values.persistence.storageClass }}" - {{- end }} - {{- end }} - {{- end }} diff --git a/infra/charts/feast/charts/kafka/templates/tests/test_topic_create_consume_produce.yaml b/infra/charts/feast/charts/kafka/templates/tests/test_topic_create_consume_produce.yaml deleted file mode 100644 index 3e7f4480daf..00000000000 --- a/infra/charts/feast/charts/kafka/templates/tests/test_topic_create_consume_produce.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: "{{ .Release.Name }}-test-topic-create-consume-produce" - annotations: - "helm.sh/hook": test-success -spec: - containers: - - name: {{ .Release.Name }}-test-consume - image: {{ .Values.image }}:{{ .Values.imageTag }} - command: - - sh - - -c - - | - set -ex - # Create the topic - kafka-topics --zookeeper {{ include "zookeeper.url" . }} --topic helm-test-topic-create-consume-produce --create --partitions 1 --replication-factor 1 --if-not-exists && \ - # Create a message - MESSAGE="`date -u`" && \ - # Produce a test message to the topic - echo "$MESSAGE" | kafka-console-producer --broker-list {{ include "kafka.fullname" . }}:9092 --topic helm-test-topic-create-consume-produce && \ - # Consume a test message from the topic - kafka-console-consumer --bootstrap-server {{ include "kafka.fullname" . }}-headless:9092 --topic helm-test-topic-create-consume-produce --from-beginning --timeout-ms 5000 | grep "$MESSAGE" - restartPolicy: Never diff --git a/infra/charts/feast/charts/kafka/values.yaml b/infra/charts/feast/charts/kafka/values.yaml deleted file mode 100644 index f1e9664a798..00000000000 --- a/infra/charts/feast/charts/kafka/values.yaml +++ /dev/null @@ -1,503 +0,0 @@ -# ------------------------------------------------------------------------------ -# Kafka: -# ------------------------------------------------------------------------------ - -## The StatefulSet installs 3 pods by default -replicas: 3 - -## The kafka image repository -image: "confluentinc/cp-kafka" - -## The kafka image tag -imageTag: "5.0.1" # Confluent image for Kafka 2.0.0 - -## Specify a imagePullPolicy -## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images -imagePullPolicy: "IfNotPresent" - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -resources: {} - # limits: - # cpu: 200m - # memory: 1536Mi - # requests: - # cpu: 100m - # memory: 1024Mi -kafkaHeapOptions: "-Xmx1G -Xms1G" - -## Optional Container Security context -securityContext: {} - -## The StatefulSet Update Strategy which Kafka will use when changes are applied. -## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies -updateStrategy: - type: "OnDelete" - -## Start and stop pods in Parallel or OrderedReady (one-by-one.) Note - Can not change after first release. -## ref: https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#pod-management-policy -podManagementPolicy: OrderedReady - -## Useful if using any custom authorizer -## Pass in some secrets to use (if required) -# secrets: -# - name: myKafkaSecret -# keys: -# - username -# - password -# # mountPath: /opt/kafka/secret -# - name: myZkSecret -# keys: -# - user -# - pass -# mountPath: /opt/zookeeper/secret - - -## The subpath within the Kafka container's PV where logs will be stored. -## This is combined with `persistence.mountPath`, to create, by default: /opt/kafka/data/logs -logSubPath: "logs" - -## Use an alternate scheduler, e.g. "stork". -## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ -## -# schedulerName: - -## Use an alternate serviceAccount -## Useful when using images in custom repositories -# serviceAccountName: - -## Set a pod priorityClassName -# priorityClassName: high-priority - -## Pod scheduling preferences (by default keep pods within a release on separate nodes). -## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity -## By default we don't set affinity -affinity: {} -## Alternatively, this typical example defines: -## antiAffinity (to keep Kafka pods on separate pods) -## and affinity (to encourage Kafka pods to be collocated with Zookeeper pods) -# affinity: -# podAntiAffinity: -# requiredDuringSchedulingIgnoredDuringExecution: -# - labelSelector: -# matchExpressions: -# - key: app -# operator: In -# values: -# - kafka -# topologyKey: "kubernetes.io/hostname" -# podAffinity: -# preferredDuringSchedulingIgnoredDuringExecution: -# - weight: 50 -# podAffinityTerm: -# labelSelector: -# matchExpressions: -# - key: app -# operator: In -# values: -# - zookeeper -# topologyKey: "kubernetes.io/hostname" - -## Node labels for pod assignment -## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector -nodeSelector: {} - -## Readiness probe config. -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ -## -readinessProbe: - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 3 - -## Period to wait for broker graceful shutdown (sigterm) before pod is killed (sigkill) -## ref: https://kubernetes-v1-4.github.io/docs/user-guide/production-pods/#lifecycle-hooks-and-termination-notice -## ref: https://kafka.apache.org/10/documentation.html#brokerconfigs controlled.shutdown.* -terminationGracePeriodSeconds: 60 - -# Tolerations for nodes that have taints on them. -# Useful if you want to dedicate nodes to just run kafka -# https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ -tolerations: [] -# tolerations: -# - key: "key" -# operator: "Equal" -# value: "value" -# effect: "NoSchedule" - -## Headless service. -## -headless: - # annotations: - # targetPort: - port: 9092 - -## External access. -## -external: - enabled: false - # type can be either NodePort or LoadBalancer - type: NodePort - # annotations: - # service.beta.kubernetes.io/openstack-internal-load-balancer: "true" - dns: - useInternal: false - useExternal: true - # If using external service type LoadBalancer and external dns, set distinct to true below. - # This creates an A record for each statefulset pod/broker. You should then map the - # A record of the broker to the EXTERNAL IP given by the LoadBalancer in your DNS server. - distinct: false - servicePort: 19092 - firstListenerPort: 31090 - domain: cluster.local - loadBalancerIP: [] - loadBalancerSourceRanges: [] - init: - image: "lwolf/kubectl_deployer" - imageTag: "0.4" - imagePullPolicy: "IfNotPresent" - -# Annotation to be added to Kafka pods -podAnnotations: {} - -# Labels to be added to Kafka pods -podLabels: {} - # service: broker - # team: developers - -podDisruptionBudget: {} - # maxUnavailable: 1 # Limits how many Kafka pods may be unavailable due to voluntary disruptions. - -## Configuration Overrides. Specify any Kafka settings you would like set on the StatefulSet -## here in map format, as defined in the official docs. -## ref: https://kafka.apache.org/documentation/#brokerconfigs -## -configurationOverrides: - "confluent.support.metrics.enable": false # Disables confluent metric submission - # "auto.leader.rebalance.enable": true - # "auto.create.topics.enable": true - # "controlled.shutdown.enable": true - # "controlled.shutdown.max.retries": 100 - - ## Options required for external access via NodePort - ## ref: - ## - http://kafka.apache.org/documentation/#security_configbroker - ## - https://cwiki.apache.org/confluence/display/KAFKA/KIP-103%3A+Separation+of+Internal+and+External+traffic - ## - ## Setting "advertised.listeners" here appends to "PLAINTEXT://${POD_IP}:9092,", ensure you update the domain - ## If external service type is Nodeport: - # "advertised.listeners": |- - # EXTERNAL://kafka.cluster.local:$((31090 + ${KAFKA_BROKER_ID})) - ## If external service type is LoadBalancer and distinct is true: - # "advertised.listeners": |- - # EXTERNAL://kafka-$((${KAFKA_BROKER_ID})).cluster.local:19092 - ## If external service type is LoadBalancer and distinct is false: - # "advertised.listeners": |- - # EXTERNAL://${LOAD_BALANCER_IP}:31090 - ## Uncomment to define the EXTERNAL Listener protocol - # "listener.security.protocol.map": |- - # PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT - -## set extra ENVs -# key: "value" -envOverrides: {} - - -## A collection of additional ports to expose on brokers (formatted as normal containerPort yaml) -# Useful when the image exposes metrics (like prometheus, etc.) through a javaagent instead of a sidecar -additionalPorts: {} - -## Persistence configuration. Specify if and how to persist data to a persistent volume. -## -persistence: - enabled: true - - ## The size of the PersistentVolume to allocate to each Kafka Pod in the StatefulSet. For - ## production servers this number should likely be much larger. - ## - size: "1Gi" - - ## The location within the Kafka container where the PV will mount its storage and Kafka will - ## store its logs. - ## - mountPath: "/opt/kafka/data" - - ## Kafka data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: - -jmx: - ## Rules to apply to the Prometheus JMX Exporter. Note while lots of stats have been cleaned and exposed, - ## there are still more stats to clean up and expose, others will never get exposed. They keep lots of duplicates - ## that can be derived easily. The configMap in this chart cleans up the metrics it exposes to be in a Prometheus - ## format, eg topic, broker are labels and not part of metric name. Improvements are gladly accepted and encouraged. - configMap: - - ## Allows disabling the default configmap, note a configMap is needed - enabled: true - - ## Allows setting values to generate confimap - ## To allow all metrics through (warning its crazy excessive) comment out below `overrideConfig` and set - ## `whitelistObjectNames: []` - overrideConfig: {} - # jmxUrl: service:jmx:rmi:///jndi/rmi://127.0.0.1:5555/jmxrmi - # lowercaseOutputName: true - # lowercaseOutputLabelNames: true - # ssl: false - # rules: - # - pattern: ".*" - - ## If you would like to supply your own ConfigMap for JMX metrics, supply the name of that - ## ConfigMap as an `overrideName` here. - overrideName: "" - - ## Port the jmx metrics are exposed in native jmx format, not in Prometheus format - port: 5555 - - ## JMX Whitelist Objects, can be set to control which JMX metrics are exposed. Only whitelisted - ## values will be exposed via JMX Exporter. They must also be exposed via Rules. To expose all metrics - ## (warning its crazy excessive and they aren't formatted in a prometheus style) (1) `whitelistObjectNames: []` - ## (2) commented out above `overrideConfig`. - whitelistObjectNames: # [] - - kafka.controller:* - - kafka.server:* - - java.lang:* - - kafka.network:* - - kafka.log:* - -## Prometheus Exporters / Metrics -## -prometheus: - ## Prometheus JMX Exporter: exposes the majority of Kafkas metrics - jmx: - enabled: false - - ## The image to use for the metrics collector - image: solsson/kafka-prometheus-jmx-exporter@sha256 - - ## The image tag to use for the metrics collector - imageTag: a23062396cd5af1acdf76512632c20ea6be76885dfc20cd9ff40fb23846557e8 - - ## Interval at which Prometheus scrapes metrics, note: only used by Prometheus Operator - interval: 10s - - ## Timeout at which Prometheus timeouts scrape run, note: only used by Prometheus Operator - scrapeTimeout: 10s - - ## Port jmx-exporter exposes Prometheus format metrics to scrape - port: 5556 - - resources: {} - # limits: - # cpu: 200m - # memory: 1Gi - # requests: - # cpu: 100m - # memory: 100Mi - - ## Prometheus Kafka Exporter: exposes complimentary metrics to JMX Exporter - kafka: - enabled: false - - ## The image to use for the metrics collector - image: danielqsj/kafka-exporter - - ## The image tag to use for the metrics collector - imageTag: v1.2.0 - - ## Interval at which Prometheus scrapes metrics, note: only used by Prometheus Operator - interval: 10s - - ## Timeout at which Prometheus timeouts scrape run, note: only used by Prometheus Operator - scrapeTimeout: 10s - - ## Port kafka-exporter exposes for Prometheus to scrape metrics - port: 9308 - - ## Resource limits - resources: {} -# limits: -# cpu: 200m -# memory: 1Gi -# requests: -# cpu: 100m -# memory: 100Mi - - # Tolerations for nodes that have taints on them. - # Useful if you want to dedicate nodes to just run kafka-exporter - # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - tolerations: [] - # tolerations: - # - key: "key" - # operator: "Equal" - # value: "value" - # effect: "NoSchedule" - - ## Pod scheduling preferences (by default keep pods within a release on separate nodes). - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - ## By default we don't set affinity - affinity: {} - ## Alternatively, this typical example defines: - ## affinity (to encourage Kafka Exporter pods to be collocated with Kafka pods) - # affinity: - # podAffinity: - # preferredDuringSchedulingIgnoredDuringExecution: - # - weight: 50 - # podAffinityTerm: - # labelSelector: - # matchExpressions: - # - key: app - # operator: In - # values: - # - kafka - # topologyKey: "kubernetes.io/hostname" - - ## Node labels for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - nodeSelector: {} - - operator: - ## Are you using Prometheus Operator? - enabled: false - - serviceMonitor: - # Namespace in which to install the ServiceMonitor resource. - namespace: monitoring - # Use release namespace instead - releaseNamespace: false - - ## Defaults to whats used if you follow CoreOS [Prometheus Install Instructions](https://github.com/coreos/prometheus-operator/tree/master/helm#tldr) - ## [Prometheus Selector Label](https://github.com/coreos/prometheus-operator/blob/master/helm/prometheus/templates/prometheus.yaml#L65) - ## [Kube Prometheus Selector Label](https://github.com/coreos/prometheus-operator/blob/master/helm/kube-prometheus/values.yaml#L298) - selector: - prometheus: kube-prometheus - - prometheusRule: - ## Add Prometheus Rules? - enabled: false - - ## Namespace in which to install the PrometheusRule resource. - namespace: monitoring - # Use release namespace instead - releaseNamespace: false - - ## Defaults to whats used if you follow CoreOS [Prometheus Install Instructions](https://github.com/coreos/prometheus-operator/tree/master/helm#tldr) - ## [Prometheus Selector Label](https://github.com/coreos/prometheus-operator/blob/master/helm/prometheus/templates/prometheus.yaml#L65) - ## [Kube Prometheus Selector Label](https://github.com/coreos/prometheus-operator/blob/master/helm/kube-prometheus/values.yaml#L298) - selector: - prometheus: kube-prometheus - - ## Some example rules. - ## e.g. max(kafka_controller_kafkacontroller_activecontrollercount_value{service="my-kafka-release"}) by (service) < 1 - rules: - - alert: KafkaNoActiveControllers - annotations: - message: The number of active controllers in {{ "{{" }} $labels.namespace {{ "}}" }} is less than 1. This usually means that some of the Kafka nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one whilst monitoring the under-replicated partitions graph). - expr: max(kafka_controller_kafkacontroller_activecontrollercount_value) by (namespace) < 1 - for: 5m - labels: - severity: critical - - alert: KafkaMultipleActiveControllers - annotations: - message: The number of active controllers in {{ "{{" }} $labels.namespace {{ "}}" }} is greater than 1. This usually means that some of the Kafka nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one whilst monitoring the under-replicated partitions graph). - expr: max(kafka_controller_kafkacontroller_activecontrollercount_value) by (namespace) > 1 - for: 5m - labels: - severity: critical - -## Kafka Config job configuration -## -configJob: - ## Specify the number of retries before considering kafka-config job as failed. - ## https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#pod-backoff-failure-policy - backoffLimit: 6 - -## Topic creation and configuration. -## The job will be run on a deployment only when the config has been changed. -## - If 'partitions' and 'replicationFactor' are specified we create the topic (with --if-not-exists.) -## - If 'partitions', 'replicationFactor' and 'reassignPartitions' are specified we reassign the partitions to -## increase the replication factor of an existing topic. -## - If 'partitions' is specified we 'alter' the number of partitions. This will -## silently and safely fail if the new setting isn’t strictly larger than the old (i.e. a NOOP.) Do be aware of the -## implications for keyed topics (ref: https://docs.confluent.io/current/kafka/post-deployment.html#admin-operations) -## - If 'defaultConfig' is specified it's deleted from the topic configuration. If it isn't present, -## it will silently and safely fail. -## - If 'config' is specified it's added to the topic configuration. -## -## Note: To increase the 'replicationFactor' of a topic, 'reassignPartitions' must be set to true (see above). -## -topics: [] - # - name: myExistingTopicConfig - # config: "cleanup.policy=compact,delete.retention.ms=604800000" - # - name: myExistingTopicReassignPartitions - # partitions: 8 - # replicationFactor: 5 - # reassignPartitions: true - # - name: myExistingTopicPartitions - # partitions: 8 - # - name: myNewTopicWithConfig - # partitions: 8 - # replicationFactor: 3 - # defaultConfig: "segment.bytes,segment.ms" - # config: "cleanup.policy=compact,delete.retention.ms=604800000" - # - name: myAclTopicPartitions - # partitions: 8 - # acls: - # - user: read - # operations: [ Read ] - # - user: read_and_write - # operations: - # - Read - # - Write - # - user: all - # operations: [ All ] - -# ------------------------------------------------------------------------------ -# Zookeeper: -# ------------------------------------------------------------------------------ - -zookeeper: - ## If true, install the Zookeeper chart alongside Kafka - ## ref: https://github.com/kubernetes/charts/tree/master/incubator/zookeeper - enabled: true - - ## Configure Zookeeper resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - resources: ~ - - ## Environmental variables to set in Zookeeper - env: - ## The JVM heap size to allocate to Zookeeper - ZK_HEAP_SIZE: "1G" - - persistence: - enabled: false - ## The amount of PV storage allocated to each Zookeeper pod in the statefulset - # size: "2Gi" - - ## Specify a Zookeeper imagePullPolicy - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - image: - PullPolicy: "IfNotPresent" - - ## If the Zookeeper Chart is disabled a URL and port are required to connect - url: "" - port: 2181 - - ## Pod scheduling preferences (by default keep pods within a release on separate nodes). - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - ## By default we don't set affinity: - affinity: {} # Criteria by which pod label-values influence scheduling for zookeeper pods. - # podAntiAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # - topologyKey: "kubernetes.io/hostname" - # labelSelector: - # matchLabels: - # release: zookeeper diff --git a/infra/charts/feast/charts/postgresql-8.6.1.tgz b/infra/charts/feast/charts/postgresql-8.6.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..c1ee74e8e82c98dbd19d6df0ae72b4dc82179515 GIT binary patch literal 31082 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"M8o^ZV=z>2RW=Zi8=dQ?=U}FdNvP)szOBaGH$o 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 Bh#3F? literal 0 HcmV?d00001 diff --git a/infra/charts/feast/charts/postgresql/.helmignore b/infra/charts/feast/charts/postgresql/.helmignore deleted file mode 100644 index a1c17ae4508..00000000000 --- a/infra/charts/feast/charts/postgresql/.helmignore +++ /dev/null @@ -1,2 +0,0 @@ -.git -OWNERS \ No newline at end of file diff --git a/infra/charts/feast/charts/postgresql/Chart.yaml b/infra/charts/feast/charts/postgresql/Chart.yaml deleted file mode 100644 index f7b07dc0599..00000000000 --- a/infra/charts/feast/charts/postgresql/Chart.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: v1 -name: postgresql -version: 8.6.1 -appVersion: 11.7.0 -description: Chart for PostgreSQL, an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance. -keywords: - - postgresql - - postgres - - database - - sql - - replication - - cluster -home: https://www.postgresql.org/ -icon: https://bitnami.com/assets/stacks/postgresql/img/postgresql-stack-110x117.png -sources: - - https://github.com/bitnami/bitnami-docker-postgresql -maintainers: - - name: Bitnami - email: containers@bitnami.com - - name: desaintmartin - email: cedric@desaintmartin.fr -engine: gotpl diff --git a/infra/charts/feast/charts/postgresql/README.md b/infra/charts/feast/charts/postgresql/README.md deleted file mode 100644 index 1db8289f993..00000000000 --- a/infra/charts/feast/charts/postgresql/README.md +++ /dev/null @@ -1,566 +0,0 @@ -# PostgreSQL - -[PostgreSQL](https://www.postgresql.org/) is an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance. - -For HA, please see [this repo](https://github.com/bitnami/charts/tree/master/bitnami/postgresql-ha) - -## TL;DR; - -```console -$ helm install my-release stable/postgresql -``` - -## Introduction - -This chart bootstraps a [PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -Bitnami charts can be used with [Kubeapps](https://kubeapps.com/) for deployment and management of Helm Charts in clusters. This chart has been tested to work with NGINX Ingress, cert-manager, fluentd and Prometheus on top of the [BKPR](https://kubeprod.io/). - -## Prerequisites - -- Kubernetes 1.12+ -- Helm 2.11+ or Helm 3.0-beta3+ -- PV provisioner support in the underlying infrastructure - -## Installing the Chart -To install the chart with the release name `my-release`: - -```console -$ helm install my-release stable/postgresql -``` - -The command deploys PostgreSQL on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. - -> **Tip**: List all releases using `helm list` - -## 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. - -## Parameters - -The following tables lists the configurable parameters of the PostgreSQL chart and their default values. - -| Parameter | Description | Default | -|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------| -| `global.imageRegistry` | Global Docker Image registry | `nil` | -| `global.postgresql.postgresqlDatabase` | PostgreSQL database (overrides `postgresqlDatabase`) | `nil` | -| `global.postgresql.postgresqlUsername` | PostgreSQL username (overrides `postgresqlUsername`) | `nil` | -| `global.postgresql.existingSecret` | Name of existing secret to use for PostgreSQL passwords (overrides `existingSecret`) | `nil` | -| `global.postgresql.postgresqlPassword` | PostgreSQL admin password (overrides `postgresqlPassword`) | `nil` | -| `global.postgresql.servicePort` | PostgreSQL port (overrides `service.port`) | `nil` | -| `global.postgresql.replicationPassword` | Replication user password (overrides `replication.password`) | `nil` | -| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) | -| `global.storageClass` | Global storage class for dynamic provisioning | `nil` | -| `image.registry` | PostgreSQL Image registry | `docker.io` | -| `image.repository` | PostgreSQL Image name | `bitnami/postgresql` | -| `image.tag` | PostgreSQL Image tag | `{TAG_NAME}` | -| `image.pullPolicy` | PostgreSQL Image pull policy | `IfNotPresent` | -| `image.pullSecrets` | Specify Image pull secrets | `nil` (does not add image pull secrets to deployed pods) | -| `image.debug` | Specify if debug values should be set | `false` | -| `nameOverride` | String to partially override postgresql.fullname template with a string (will prepend the release name) | `nil` | -| `fullnameOverride` | String to fully override postgresql.fullname template with a string | `nil` | -| `volumePermissions.enabled` | Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) | `false` | -| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | -| `volumePermissions.image.repository` | Init container volume-permissions image name | `bitnami/minideb` | -| `volumePermissions.image.tag` | Init container volume-permissions image tag | `buster` | -| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `Always` | -| `volumePermissions.securityContext.runAsUser` | User ID for the init container (when facing issues in OpenShift or uid unknown, try value "auto") | `0` | -| `usePasswordFile` | Have the secrets mounted as a file instead of env vars | `false` | -| `ldap.enabled` | Enable LDAP support | `false` | -| `ldap.existingSecret` | Name of existing secret to use for LDAP passwords | `nil` | -| `ldap.url` | LDAP URL beginning in the form `ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]]` | `nil` | -| `ldap.server` | IP address or name of the LDAP server. | `nil` | -| `ldap.port` | Port number on the LDAP server to connect to | `nil` | -| `ldap.scheme` | Set to `ldaps` to use LDAPS. | `nil` | -| `ldap.tls` | Set to `1` to use TLS encryption | `nil` | -| `ldap.prefix` | String to prepend to the user name when forming the DN to bind | `nil` | -| `ldap.suffix` | String to append to the user name when forming the DN to bind | `nil` | -| `ldap.search_attr` | Attribute to match agains the user name in the search | `nil` | -| `ldap.search_filter` | The search filter to use when doing search+bind authentication | `nil` | -| `ldap.baseDN` | Root DN to begin the search for the user in | `nil` | -| `ldap.bindDN` | DN of user to bind to LDAP | `nil` | -| `ldap.bind_password` | Password for the user to bind to LDAP | `nil` | -| `replication.enabled` | Enable replication | `false` | -| `replication.user` | Replication user | `repl_user` | -| `replication.password` | Replication user password | `repl_password` | -| `replication.slaveReplicas` | Number of slaves replicas | `1` | -| `replication.synchronousCommit` | Set synchronous commit mode. Allowed values: `on`, `remote_apply`, `remote_write`, `local` and `off` | `off` | -| `replication.numSynchronousReplicas` | Number of replicas that will have synchronous replication. Note: Cannot be greater than `replication.slaveReplicas`. | `0` | -| `replication.applicationName` | Cluster application name. Useful for advanced replication settings | `my_application` | -| `existingSecret` | Name of existing secret to use for PostgreSQL passwords. The secret has to contain the keys `postgresql-postgres-password` which is the password for `postgresqlUsername` when it is different of `postgres`, `postgresql-password` which will override `postgresqlPassword`, `postgresql-replication-password` which will override `replication.password` and `postgresql-ldap-password` which will be sed to authenticate on LDAP. | `nil` | -| `postgresqlPostgresPassword` | PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`) | _random 10 character alphanumeric string_ | -| `postgresqlUsername` | PostgreSQL admin user | `postgres` | -| `postgresqlPassword` | PostgreSQL admin password | _random 10 character alphanumeric string_ | -| `postgresqlDatabase` | PostgreSQL database | `nil` | -| `postgresqlDataDir` | PostgreSQL data dir folder | `/bitnami/postgresql` (same value as persistence.mountPath) | -| `extraEnv` | Any extra environment variables you would like to pass on to the pod. The value is evaluated as a template. | `[]` | -| `extraEnvVarsCM` | Name of a Config Map containing extra environment variables you would like to pass on to the pod. | `nil` | -| `postgresqlInitdbArgs` | PostgreSQL initdb extra arguments | `nil` | -| `postgresqlInitdbWalDir` | PostgreSQL location for transaction log | `nil` | -| `postgresqlConfiguration` | Runtime Config Parameters | `nil` | -| `postgresqlExtendedConf` | Extended Runtime Config Parameters (appended to main or default configuration) | `nil` | -| `pgHbaConfiguration` | Content of pg_hba.conf | `nil (do not create pg_hba.conf)` | -| `configurationConfigMap` | ConfigMap with the PostgreSQL configuration files (Note: Overrides `postgresqlConfiguration` and `pgHbaConfiguration`). The value is evaluated as a template. | `nil` | -| `extendedConfConfigMap` | ConfigMap with the extended PostgreSQL configuration files. The value is evaluated as a template. | `nil` | -| `initdbScripts` | Dictionary of initdb scripts | `nil` | -| `initdbUsername` | PostgreSQL user to execute the .sql and sql.gz scripts | `nil` | -| `initdbPassword` | Password for the user specified in `initdbUsername` | `nil` | -| `initdbScriptsConfigMap` | ConfigMap with the initdb scripts (Note: Overrides `initdbScripts`). The value is evaluated as a template. | `nil` | -| `initdbScriptsSecret` | Secret with initdb scripts that contain sensitive information (Note: can be used with `initdbScriptsConfigMap` or `initdbScripts`). The value is evaluated as a template. | `nil` | -| `service.type` | Kubernetes Service type | `ClusterIP` | -| `service.port` | PostgreSQL port | `5432` | -| `service.nodePort` | Kubernetes Service nodePort | `nil` | -| `service.annotations` | Annotations for PostgreSQL service, the value is evaluated as a template. | {} | -| `service.loadBalancerIP` | loadBalancerIP if service type is `LoadBalancer` | `nil` | -| `service.loadBalancerSourceRanges` | Address that are allowed when svc is LoadBalancer | [] | -| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | -| `shmVolume.enabled` | Enable emptyDir volume for /dev/shm for master and slave(s) Pod(s) | `true` | -| `shmVolume.chmod.enabled` | Run at init chmod 777 of the /dev/shm (ignored if `volumePermissions.enabled` is `false`) | `true` | -| `persistence.enabled` | Enable persistence using PVC | `true` | -| `persistence.existingClaim` | Provide an existing `PersistentVolumeClaim`, the value is evaluated as a template. | `nil` | -| `persistence.mountPath` | Path to mount the volume at | `/bitnami/postgresql` | -| `persistence.subPath` | Subdirectory of the volume to mount at | `""` | -| `persistence.storageClass` | PVC Storage Class for PostgreSQL volume | `nil` | -| `persistence.accessModes` | PVC Access Mode for PostgreSQL volume | `[ReadWriteOnce]` | -| `persistence.size` | PVC Storage Request for PostgreSQL volume | `8Gi` | -| `persistence.annotations` | Annotations for the PVC | `{}` | -| `master.nodeSelector` | Node labels for pod assignment (postgresql master) | `{}` | -| `master.affinity` | Affinity labels for pod assignment (postgresql master) | `{}` | -| `master.tolerations` | Toleration labels for pod assignment (postgresql master) | `[]` | -| `master.anotations` | Map of annotations to add to the statefulset (postgresql master) | `{}` | -| `master.labels` | Map of labels to add to the statefulset (postgresql master) | `{}` | -| `master.podAnnotations` | Map of annotations to add to the pods (postgresql master) | `{}` | -| `master.podLabels` | Map of labels to add to the pods (postgresql master) | `{}` | -| `master.priorityClassName` | Priority Class to use for each pod (postgresql master) | `nil` | -| `master.extraInitContainers` | Additional init containers to add to the pods (postgresql master) | `[]` | -| `master.extraVolumeMounts` | Additional volume mounts to add to the pods (postgresql master) | `[]` | -| `master.extraVolumes` | Additional volumes to add to the pods (postgresql master) | `[]` | -| `master.sidecars` | Add additional containers to the pod | `[]` | -| `slave.nodeSelector` | Node labels for pod assignment (postgresql slave) | `{}` | -| `slave.affinity` | Affinity labels for pod assignment (postgresql slave) | `{}` | -| `slave.tolerations` | Toleration labels for pod assignment (postgresql slave) | `[]` | -| `slave.anotations` | Map of annotations to add to the statefulsets (postgresql slave) | `{}` | -| `slave.labels` | Map of labels to add to the statefulsets (postgresql slave) | `{}` | -| `slave.podAnnotations` | Map of annotations to add to the pods (postgresql slave) | `{}` | -| `slave.podLabels` | Map of labels to add to the pods (postgresql slave) | `{}` | -| `slave.priorityClassName` | Priority Class to use for each pod (postgresql slave) | `nil` | -| `slave.extraInitContainers` | Additional init containers to add to the pods (postgresql slave) | `[]` | -| `slave.extraVolumeMounts` | Additional volume mounts to add to the pods (postgresql slave) | `[]` | -| `slave.extraVolumes` | Additional volumes to add to the pods (postgresql slave) | `[]` | -| `slave.sidecars` | Add additional containers to the pod | `[]` | -| `terminationGracePeriodSeconds` | Seconds the pod needs to terminate gracefully | `nil` | -| `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `250m` | -| `securityContext.enabled` | Enable security context | `true` | -| `securityContext.fsGroup` | Group ID for the container | `1001` | -| `securityContext.runAsUser` | User ID for the container | `1001` | -| `serviceAccount.enabled` | Enable service account (Note: Service Account will only be automatically created if `serviceAccount.name` is not set) | `false` | -| `serviceAcccount.name` | Name of existing service account | `nil` | -| `livenessProbe.enabled` | Would you like a livenessProbe to be enabled | `true` | -| `networkPolicy.enabled` | Enable NetworkPolicy | `false` | -| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | -| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which ingress traffic could be allowed | `nil` | -| `livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 30 | -| `livenessProbe.periodSeconds` | How often to perform the probe | 10 | -| `livenessProbe.timeoutSeconds` | When the probe times out | 5 | -| `livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 | -| `livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 | -| `readinessProbe.enabled` | would you like a readinessProbe to be enabled | `true` | -| `readinessProbe.initialDelaySeconds` | Delay before readiness probe is initiated | 5 | -| `readinessProbe.periodSeconds` | How often to perform the probe | 10 | -| `readinessProbe.timeoutSeconds` | When the probe times out | 5 | -| `readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 | -| `readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 | -| `metrics.enabled` | Start a prometheus exporter | `false` | -| `metrics.service.type` | Kubernetes Service type | `ClusterIP` | -| `service.clusterIP` | Static clusterIP or None for headless services | `nil` | -| `metrics.service.annotations` | Additional annotations for metrics exporter pod | `{ prometheus.io/scrape: "true", prometheus.io/port: "9187"}` | -| `metrics.service.loadBalancerIP` | loadBalancerIP if redis metrics service type is `LoadBalancer` | `nil` | -| `metrics.serviceMonitor.enabled` | Set this to `true` to create ServiceMonitor for Prometheus operator | `false` | -| `metrics.serviceMonitor.additionalLabels` | Additional labels that can be used so ServiceMonitor will be discovered by Prometheus | `{}` | -| `metrics.serviceMonitor.namespace` | Optional namespace in which to create ServiceMonitor | `nil` | -| `metrics.serviceMonitor.interval` | Scrape interval. If not set, the Prometheus default scrape interval is used | `nil` | -| `metrics.serviceMonitor.scrapeTimeout` | Scrape timeout. If not set, the Prometheus default scrape timeout is used | `nil` | -| `metrics.prometheusRule.enabled` | Set this to true to create prometheusRules for Prometheus operator | `false` | -| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so prometheusRules will be discovered by Prometheus | `{}` | -| `metrics.prometheusRule.namespace` | namespace where prometheusRules resource should be created | the same namespace as postgresql | -| `metrics.prometheusRule.rules` | [rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) to be created, check values for an example. | `[]` | -| `metrics.image.registry` | PostgreSQL Image registry | `docker.io` | -| `metrics.image.repository` | PostgreSQL Image name | `bitnami/postgres-exporter` | -| `metrics.image.tag` | PostgreSQL Image tag | `{TAG_NAME}` | -| `metrics.image.pullPolicy` | PostgreSQL Image pull policy | `IfNotPresent` | -| `metrics.image.pullSecrets` | Specify Image pull secrets | `nil` (does not add image pull secrets to deployed pods) | -| `metrics.customMetrics` | Additional custom metrics | `nil` | -| `metrics.securityContext.enabled` | Enable security context for metrics | `false` | -| `metrics.securityContext.runAsUser` | User ID for the container for metrics | `1001` | -| `metrics.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 30 | -| `metrics.livenessProbe.periodSeconds` | How often to perform the probe | 10 | -| `metrics.livenessProbe.timeoutSeconds` | When the probe times out | 5 | -| `metrics.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 | -| `metrics.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 | -| `metrics.readinessProbe.enabled` | would you like a readinessProbe to be enabled | `true` | -| `metrics.readinessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 5 | -| `metrics.readinessProbe.periodSeconds` | How often to perform the probe | 10 | -| `metrics.readinessProbe.timeoutSeconds` | When the probe times out | 5 | -| `metrics.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 | -| `metrics.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 | -| `updateStrategy` | Update strategy policy | `{type: "RollingUpdate"}` | - -Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, - -```console -$ helm install my-release \ - --set postgresqlPassword=secretpassword,postgresqlDatabase=my-database \ - stable/postgresql -``` - -The above command sets the PostgreSQL `postgres` account password to `secretpassword`. Additionally it creates a database named `my-database`. - -Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, - -```console -$ helm install my-release -f values.yaml stable/postgresql -``` - -> **Tip**: You can use the default [values.yaml](values.yaml) - -## Configuration and installation details - -### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) - -It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. - -Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. - -### Production configuration and horizontal scaling - -This chart includes a `values-production.yaml` file where you can find some parameters oriented to production configuration in comparison to the regular `values.yaml`. You can use this file instead of the default one. - -- Enable replication: -```diff -- replication.enabled: false -+ replication.enabled: true -``` - -- Number of slaves replicas: -```diff -- replication.slaveReplicas: 1 -+ replication.slaveReplicas: 2 -``` - -- Set synchronous commit mode: -```diff -- replication.synchronousCommit: "off" -+ replication.synchronousCommit: "on" -``` - -- Number of replicas that will have synchronous replication: -```diff -- replication.numSynchronousReplicas: 0 -+ replication.numSynchronousReplicas: 1 -``` - -- Start a prometheus exporter: -```diff -- metrics.enabled: false -+ metrics.enabled: true -``` - -To horizontally scale this chart, you can use the `--replicas` flag to modify the number of nodes in your PostgreSQL deployment. Also you can use the `values-production.yaml` file or modify the parameters shown above. - -### Change PostgreSQL version - -To modify the PostgreSQL version used in this chart you can specify a [valid image tag](https://hub.docker.com/r/bitnami/postgresql/tags/) using the `image.tag` parameter. For example, `image.tag=12.0.0` - -### postgresql.conf / pg_hba.conf files as configMap - -This helm chart also supports to customize the whole configuration file. - -Add your custom file to "files/postgresql.conf" in your working directory. This file will be mounted as configMap to the containers and it will be used for configuring the PostgreSQL server. - -Alternatively, you can specify PostgreSQL configuration parameters using the `postgresqlConfiguration` parameter as a dict, using camelCase, e.g. {"sharedBuffers": "500MB"}. - -In addition to these options, you can also set an external ConfigMap with all the configuration files. This is done by setting the `configurationConfigMap` parameter. Note that this will override the two previous options. - -### Allow settings to be loaded from files other than the default `postgresql.conf` - -If you don't want to provide the whole PostgreSQL configuration file and only specify certain parameters, you can add your extended `.conf` files to "files/conf.d/" in your working directory. -Those files will be mounted as configMap to the containers adding/overwriting the default configuration using the `include_dir` directive that allows settings to be loaded from files other than the default `postgresql.conf`. - -Alternatively, you can also set an external ConfigMap with all the extra configuration files. This is done by setting the `extendedConfConfigMap` parameter. Note that this will override the previous option. - -### Initialize a fresh instance - -The [Bitnami PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) image allows you to use your custom scripts to initialize a fresh instance. In order to execute the scripts, they must be located inside the chart folder `files/docker-entrypoint-initdb.d` so they can be consumed as a ConfigMap. - -Alternatively, you can specify custom scripts using the `initdbScripts` parameter as dict. - -In addition to these options, you can also set an external ConfigMap with all the initialization scripts. This is done by setting the `initdbScriptsConfigMap` parameter. Note that this will override the two previous options. If your initialization scripts contain sensitive information such as credentials or passwords, you can use the `initdbScriptsSecret` parameter. - -The allowed extensions are `.sh`, `.sql` and `.sql.gz`. - -### Sidecars - -If you need additional containers to run within the same pod as PostgreSQL (e.g. an additional metrics or logging exporter), you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. - -```yaml -# For the PostgreSQL master -master: - sidecars: - - name: your-image-name - image: your-image - imagePullPolicy: Always - ports: - - name: portname - containerPort: 1234 -# For the PostgreSQL replicas -slave: - sidecars: - - name: your-image-name - image: your-image - imagePullPolicy: Always - ports: - - name: portname - containerPort: 1234 -``` - -### Metrics - -The chart optionally can start a metrics exporter for [prometheus](https://prometheus.io). The metrics endpoint (port 9187) is not exposed and it is expected that the metrics are collected from inside the k8s cluster using something similar as the described in the [example Prometheus scrape configuration](https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml). - -The exporter allows to create custom metrics from additional SQL queries. See the Chart's `values.yaml` for an example and consult the [exporters documentation](https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file) for more details. - -### Use of global variables - -In more complex scenarios, we may have the following tree of dependencies - -``` - +--------------+ - | | - +------------+ Chart 1 +-----------+ - | | | | - | --------+------+ | - | | | - | | | - | | | - | | | - v v v -+-------+------+ +--------+------+ +--------+------+ -| | | | | | -| PostgreSQL | | Sub-chart 1 | | Sub-chart 2 | -| | | | | | -+--------------+ +---------------+ +---------------+ -``` - -The three charts below depend on the parent chart Chart 1. However, subcharts 1 and 2 may need to connect to PostgreSQL as well. In order to do so, subcharts 1 and 2 need to know the PostgreSQL credentials, so one option for deploying could be deploy Chart 1 with the following parameters: - -``` -postgresql.postgresqlPassword=testtest -subchart1.postgresql.postgresqlPassword=testtest -subchart2.postgresql.postgresqlPassword=testtest -postgresql.postgresqlDatabase=db1 -subchart1.postgresql.postgresqlDatabase=db1 -subchart2.postgresql.postgresqlDatabase=db1 -``` - -If the number of dependent sub-charts increases, installing the chart with parameters can become increasingly difficult. An alternative would be to set the credentials using global variables as follows: - -``` -global.postgresql.postgresqlPassword=testtest -global.postgresql.postgresqlDatabase=db1 -``` - -This way, the credentials will be available in all of the subcharts. - -## Persistence - -The [Bitnami PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) image stores the PostgreSQL data and configurations at the `/bitnami/postgresql` path of the container. - -Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. -See the [Parameters](#parameters) section to configure the PVC or to disable persistence. - -If you already have data in it, you will fail to sync to standby nodes for all commits, details can refer to [code](https://github.com/bitnami/bitnami-docker-postgresql/blob/8725fe1d7d30ebe8d9a16e9175d05f7ad9260c93/9.6/debian-9/rootfs/libpostgresql.sh#L518-L556). If you need to use those data, please covert them to sql and import after `helm install` finished. - -## NetworkPolicy - -To enable network policy for PostgreSQL, install [a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), and set `networkPolicy.enabled` to `true`. - -For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting the DefaultDeny namespace annotation. Note: this will enforce policy for _all_ pods in the namespace: - -```console -$ kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" -``` - -With NetworkPolicy enabled, traffic will be limited to just port 5432. - -For more precise policy, set `networkPolicy.allowExternal=false`. This will only allow pods with the generated client label to connect to PostgreSQL. -This label will be displayed in the output of a successful install. - -## Differences between Bitnami PostgreSQL image and [Docker Official](https://hub.docker.com/_/postgres) image - -- The Docker Official PostgreSQL image does not support replication. If you pass any replication environment variable, this would be ignored. The only environment variables supported by the Docker Official image are POSTGRES_USER, POSTGRES_DB, POSTGRES_PASSWORD, POSTGRES_INITDB_ARGS, POSTGRES_INITDB_WALDIR and PGDATA. All the remaining environment variables are specific to the Bitnami PostgreSQL image. -- The Bitnami PostgreSQL image is non-root by default. This requires that you run the pod with `securityContext` and updates the permissions of the volume with an `initContainer`. A key benefit of this configuration is that the pod follows security best practices and is prepared to run on Kubernetes distributions with hard security constraints like OpenShift. -- For OpenShift, one may either define the runAsUser and fsGroup accordingly, or try this more dynamic option: volumePermissions.securityContext.runAsUser="auto",securityContext.enabled=false,shmVolume.chmod.enabled=false - -### Deploy chart using Docker Official PostgreSQL Image - -From chart version 4.0.0, it is possible to use this chart with the Docker Official PostgreSQL image. -Besides specifying the new Docker repository and tag, it is important to modify the PostgreSQL data directory and volume mount point. Basically, the PostgreSQL data dir cannot be the mount point directly, it has to be a subdirectory. - -``` -helm install postgres \ - --set image.repository=postgres \ - --set image.tag=10.6 \ - --set postgresqlDataDir=/data/pgdata \ - --set persistence.mountPath=/data/ \ - stable/postgresql -``` - -## Upgrade - -It's necessary to specify the existing passwords while performing an upgrade to ensure the secrets are not updated with invalid randomly generated passwords. Remember to specify the existing values of the `postgresqlPassword` and `replication.password` parameters when upgrading the chart: - -```bash -$ helm upgrade my-release bitnami/influxdb \ - --set postgresqlPassword=[POSTGRESQL_PASSWORD] \ - --set replication.password=[REPLICATION_PASSWORD] -``` - -> Note: you need to substitute the placeholders _[POSTGRESQL_PASSWORD]_, and _[REPLICATION_PASSWORD]_ with the values obtained from instructions in the installation notes. - -## 8.0.0 - -Prefixes the port names with their protocols to comply with Istio conventions. - -If you depend on the port names in your setup, make sure to update them to reflect this change. - -## 7.1.0 - -Adds support for LDAP configuration. - -## 7.0.0 - -Helm performs a lookup for the object based on its group (apps), version (v1), and kind (Deployment). Also known as its GroupVersionKind, or GVK. Changing the GVK is considered a compatibility breaker from Kubernetes' point of view, so you cannot "upgrade" those objects to the new GVK in-place. Earlier versions of Helm 3 did not perform the lookup correctly which has since been fixed to match the spec. - -In https://github.com/helm/charts/pull/17281 the `apiVersion` of the statefulset resources was updated to `apps/v1` in tune with the api's deprecated, resulting in compatibility breakage. - -This major version bump signifies this change. - -## 6.5.7 - -In this version, the chart will use PostgreSQL with the Postgis extension included. The version used with Postgresql version 10, 11 and 12 is Postgis 2.5. It has been compiled with the following dependencies: - - - protobuf - - protobuf-c - - json-c - - geos - - proj - -## 5.0.0 - -In this version, the **chart is using PostgreSQL 11 instead of PostgreSQL 10**. You can find the main difference and notable changes in the following links: [https://www.postgresql.org/about/news/1894/](https://www.postgresql.org/about/news/1894/) and [https://www.postgresql.org/about/featurematrix/](https://www.postgresql.org/about/featurematrix/). - -For major releases of PostgreSQL, the internal data storage format is subject to change, thus complicating upgrades, you can see some errors like the following one in the logs: - -```bash -Welcome to the Bitnami postgresql container -Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-postgresql -Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-postgresql/issues -Send us your feedback at containers@bitnami.com - -INFO ==> ** Starting PostgreSQL setup ** -NFO ==> Validating settings in POSTGRESQL_* env vars.. -INFO ==> Initializing PostgreSQL database... -INFO ==> postgresql.conf file not detected. Generating it... -INFO ==> pg_hba.conf file not detected. Generating it... -INFO ==> Deploying PostgreSQL with persisted data... -INFO ==> Configuring replication parameters -INFO ==> Loading custom scripts... -INFO ==> Enabling remote connections -INFO ==> Stopping PostgreSQL... -INFO ==> ** PostgreSQL setup finished! ** - -INFO ==> ** Starting PostgreSQL ** - [1] FATAL: database files are incompatible with server - [1] DETAIL: The data directory was initialized by PostgreSQL version 10, which is not compatible with this version 11.3. -``` -In this case, you should migrate the data from the old chart to the new one following an approach similar to that described in [this section](https://www.postgresql.org/docs/current/upgrading.html#UPGRADING-VIA-PGDUMPALL) from the official documentation. Basically, create a database dump in the old chart, move and restore it in the new one. - -### 4.0.0 - -This chart will use by default the Bitnami PostgreSQL container starting from version `10.7.0-r68`. This version moves the initialization logic from node.js to bash. This new version of the chart requires setting the `POSTGRES_PASSWORD` in the slaves as well, in order to properly configure the `pg_hba.conf` file. Users from previous versions of the chart are advised to upgrade immediately. - -IMPORTANT: If you do not want to upgrade the chart version then make sure you use the `10.7.0-r68` version of the container. Otherwise, you will get this error - -``` -The POSTGRESQL_PASSWORD environment variable is empty or not set. Set the environment variable ALLOW_EMPTY_PASSWORD=yes to allow the container to be started with blank passwords. This is recommended only for development -``` - -### 3.0.0 - -This releases make it possible to specify different nodeSelector, affinity and tolerations for master and slave pods. -It also fixes an issue with `postgresql.master.fullname` helper template not obeying fullnameOverride. - -#### Breaking changes - -- `affinty` has been renamed to `master.affinity` and `slave.affinity`. -- `tolerations` has been renamed to `master.tolerations` and `slave.tolerations`. -- `nodeSelector` has been renamed to `master.nodeSelector` and `slave.nodeSelector`. - -### 2.0.0 - -In order to upgrade from the `0.X.X` branch to `1.X.X`, you should follow the below steps: - - - Obtain the service name (`SERVICE_NAME`) and password (`OLD_PASSWORD`) of the existing postgresql chart. You can find the instructions to obtain the password in the NOTES.txt, the service name can be obtained by running - - ```console -$ kubectl get svc - ``` - -- Install (not upgrade) the new version - -```console -$ helm repo update -$ helm install my-release stable/postgresql -``` - -- Connect to the new pod (you can obtain the name by running `kubectl get pods`): - -```console -$ kubectl exec -it NAME bash -``` - -- Once logged in, create a dump file from the previous database using `pg_dump`, for that we should connect to the previous postgresql chart: - -```console -$ pg_dump -h SERVICE_NAME -U postgres DATABASE_NAME > /tmp/backup.sql -``` - -After run above command you should be prompted for a password, this password is the previous chart password (`OLD_PASSWORD`). -This operation could take some time depending on the database size. - -- Once you have the backup file, you can restore it with a command like the one below: - -```console -$ psql -U postgres DATABASE_NAME < /tmp/backup.sql -``` - -In this case, you are accessing to the local postgresql, so the password should be the new one (you can find it in NOTES.txt). - -If you want to restore the database and the database schema does not exist, it is necessary to first follow the steps described below. - -```console -$ psql -U postgres -postgres=# drop database DATABASE_NAME; -postgres=# create database DATABASE_NAME; -postgres=# create user USER_NAME; -postgres=# alter role USER_NAME with password 'BITNAMI_USER_PASSWORD'; -postgres=# grant all privileges on database DATABASE_NAME to USER_NAME; -postgres=# alter database DATABASE_NAME owner to USER_NAME; -``` diff --git a/infra/charts/feast/charts/postgresql/ci/default-values.yaml b/infra/charts/feast/charts/postgresql/ci/default-values.yaml deleted file mode 100644 index fc2ba605ada..00000000000 --- a/infra/charts/feast/charts/postgresql/ci/default-values.yaml +++ /dev/null @@ -1 +0,0 @@ -# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/infra/charts/feast/charts/postgresql/ci/shmvolume-disabled-values.yaml b/infra/charts/feast/charts/postgresql/ci/shmvolume-disabled-values.yaml deleted file mode 100644 index 347d3b40a8e..00000000000 --- a/infra/charts/feast/charts/postgresql/ci/shmvolume-disabled-values.yaml +++ /dev/null @@ -1,2 +0,0 @@ -shmVolume: - enabled: false diff --git a/infra/charts/feast/charts/postgresql/files/README.md b/infra/charts/feast/charts/postgresql/files/README.md deleted file mode 100644 index 1813a2feaaf..00000000000 --- a/infra/charts/feast/charts/postgresql/files/README.md +++ /dev/null @@ -1 +0,0 @@ -Copy here your postgresql.conf and/or pg_hba.conf files to use it as a config map. diff --git a/infra/charts/feast/charts/postgresql/files/conf.d/README.md b/infra/charts/feast/charts/postgresql/files/conf.d/README.md deleted file mode 100644 index 184c1875d57..00000000000 --- a/infra/charts/feast/charts/postgresql/files/conf.d/README.md +++ /dev/null @@ -1,4 +0,0 @@ -If you don't want to provide the whole configuration file and only specify certain parameters, you can copy here your extended `.conf` files. -These files will be injected as a config maps and add/overwrite the default configuration using the `include_dir` directive that allows settings to be loaded from files other than the default `postgresql.conf`. - -More info in the [bitnami-docker-postgresql README](https://github.com/bitnami/bitnami-docker-postgresql#configuration-file). diff --git a/infra/charts/feast/charts/postgresql/files/docker-entrypoint-initdb.d/README.md b/infra/charts/feast/charts/postgresql/files/docker-entrypoint-initdb.d/README.md deleted file mode 100644 index cba38091e0f..00000000000 --- a/infra/charts/feast/charts/postgresql/files/docker-entrypoint-initdb.d/README.md +++ /dev/null @@ -1,3 +0,0 @@ -You can copy here your custom `.sh`, `.sql` or `.sql.gz` file so they are executed during the first boot of the image. - -More info in the [bitnami-docker-postgresql](https://github.com/bitnami/bitnami-docker-postgresql#initializing-a-new-instance) repository. \ No newline at end of file diff --git a/infra/charts/feast/charts/postgresql/templates/NOTES.txt b/infra/charts/feast/charts/postgresql/templates/NOTES.txt deleted file mode 100644 index 3b5e6c60dfd..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/NOTES.txt +++ /dev/null @@ -1,60 +0,0 @@ -** Please be patient while the chart is being deployed ** - -PostgreSQL can be accessed via port {{ template "postgresql.port" . }} on the following DNS name from within your cluster: - - {{ template "postgresql.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - Read/Write connection -{{- if .Values.replication.enabled }} - {{ template "postgresql.fullname" . }}-read.{{ .Release.Namespace }}.svc.cluster.local - Read only connection -{{- end }} - -{{- if and .Values.postgresqlPostgresPassword (not (eq .Values.postgresqlUsername "postgres")) }} - -To get the password for "postgres" run: - - export POSTGRES_ADMIN_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "postgresql.secretName" . }} -o jsonpath="{.data.postgresql-postgres-password}" | base64 --decode) -{{- end }} - -To get the password for "{{ template "postgresql.username" . }}" run: - - export POSTGRES_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "postgresql.secretName" . }} -o jsonpath="{.data.postgresql-password}" | base64 --decode) - -To connect to your database run the following command: - - kubectl run {{ template "postgresql.fullname" . }}-client --rm --tty -i --restart='Never' --namespace {{ .Release.Namespace }} --image {{ template "postgresql.image" . }} --env="PGPASSWORD=$POSTGRES_PASSWORD" {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} - --labels="{{ template "postgresql.fullname" . }}-client=true" {{- end }} --command -- psql --host {{ template "postgresql.fullname" . }} -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} -p {{ template "postgresql.port" . }} - -{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} -Note: Since NetworkPolicy is enabled, only pods with label {{ template "postgresql.fullname" . }}-client=true" will be able to connect to this PostgreSQL cluster. -{{- end }} - -To connect to your database from outside the cluster execute the following commands: - -{{- if contains "NodePort" .Values.service.type }} - - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "postgresql.fullname" . }}) - {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host $NODE_IP --port $NODE_PORT -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} - -{{- else if contains "LoadBalancer" .Values.service.type }} - - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "postgresql.fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "postgresql.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host $SERVICE_IP --port {{ template "postgresql.port" . }} -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} - -{{- else if contains "ClusterIP" .Values.service.type }} - - kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "postgresql.fullname" . }} {{ template "postgresql.port" . }}:{{ template "postgresql.port" . }} & - {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host 127.0.0.1 -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} -p {{ template "postgresql.port" . }} - -{{- end }} - -{{- include "postgresql.validateValues" . -}} - -{{- if and (contains "bitnami/" .Values.image.repository) (not (.Values.image.tag | toString | regexFind "-r\\d+$|sha256:")) }} - -WARNING: Rolling tag detected ({{ .Values.image.repository }}:{{ .Values.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. -+info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ - -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/_helpers.tpl b/infra/charts/feast/charts/postgresql/templates/_helpers.tpl deleted file mode 100644 index 3ee55726e7d..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/_helpers.tpl +++ /dev/null @@ -1,420 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "postgresql.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). -*/}} -{{- define "postgresql.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "postgresql.master.fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- $fullname := default (printf "%s-%s" .Release.Name $name) .Values.fullnameOverride -}} -{{- if .Values.replication.enabled -}} -{{- printf "%s-%s" $fullname "master" | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s" $fullname | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} - -{{/* -Return the appropriate apiVersion for networkpolicy. -*/}} -{{- define "postgresql.networkPolicy.apiVersion" -}} -{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} -"extensions/v1beta1" -{{- else if semverCompare "^1.7-0" .Capabilities.KubeVersion.GitVersion -}} -"networking.k8s.io/v1" -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "postgresql.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Return the proper PostgreSQL image name -*/}} -{{- define "postgresql.image" -}} -{{- $registryName := .Values.image.registry -}} -{{- $repositoryName := .Values.image.repository -}} -{{- $tag := .Values.image.tag | toString -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. -Also, we can't use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} - {{- if .Values.global.imageRegistry }} - {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} - {{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} - {{- end -}} -{{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} -{{- end -}} - -{{/* -Return PostgreSQL postgres user password -*/}} -{{- define "postgresql.postgres.password" -}} -{{- if .Values.global.postgresql.postgresqlPostgresPassword }} - {{- .Values.global.postgresql.postgresqlPostgresPassword -}} -{{- else if .Values.postgresqlPostgresPassword -}} - {{- .Values.postgresqlPostgresPassword -}} -{{- else -}} - {{- randAlphaNum 10 -}} -{{- end -}} -{{- end -}} - -{{/* -Return PostgreSQL password -*/}} -{{- define "postgresql.password" -}} -{{- if .Values.global.postgresql.postgresqlPassword }} - {{- .Values.global.postgresql.postgresqlPassword -}} -{{- else if .Values.postgresqlPassword -}} - {{- .Values.postgresqlPassword -}} -{{- else -}} - {{- randAlphaNum 10 -}} -{{- end -}} -{{- end -}} - -{{/* -Return PostgreSQL replication password -*/}} -{{- define "postgresql.replication.password" -}} -{{- if .Values.global.postgresql.replicationPassword }} - {{- .Values.global.postgresql.replicationPassword -}} -{{- else if .Values.replication.password -}} - {{- .Values.replication.password -}} -{{- else -}} - {{- randAlphaNum 10 -}} -{{- end -}} -{{- end -}} - -{{/* -Return PostgreSQL username -*/}} -{{- define "postgresql.username" -}} -{{- if .Values.global.postgresql.postgresqlUsername }} - {{- .Values.global.postgresql.postgresqlUsername -}} -{{- else -}} - {{- .Values.postgresqlUsername -}} -{{- end -}} -{{- end -}} - - -{{/* -Return PostgreSQL replication username -*/}} -{{- define "postgresql.replication.username" -}} -{{- if .Values.global.postgresql.replicationUser }} - {{- .Values.global.postgresql.replicationUser -}} -{{- else -}} - {{- .Values.replication.user -}} -{{- end -}} -{{- end -}} - -{{/* -Return PostgreSQL port -*/}} -{{- define "postgresql.port" -}} -{{- if .Values.global.postgresql.servicePort }} - {{- .Values.global.postgresql.servicePort -}} -{{- else -}} - {{- .Values.service.port -}} -{{- end -}} -{{- end -}} - -{{/* -Return PostgreSQL created database -*/}} -{{- define "postgresql.database" -}} -{{- if .Values.global.postgresql.postgresqlDatabase }} - {{- .Values.global.postgresql.postgresqlDatabase -}} -{{- else if .Values.postgresqlDatabase -}} - {{- .Values.postgresqlDatabase -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper image name to change the volume permissions -*/}} -{{- define "postgresql.volumePermissions.image" -}} -{{- $registryName := .Values.volumePermissions.image.registry -}} -{{- $repositoryName := .Values.volumePermissions.image.repository -}} -{{- $tag := .Values.volumePermissions.image.tag | toString -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. -Also, we can't use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} - {{- if .Values.global.imageRegistry }} - {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} - {{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} - {{- end -}} -{{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper PostgreSQL metrics image name -*/}} -{{- define "postgresql.metrics.image" -}} -{{- $registryName := default "docker.io" .Values.metrics.image.registry -}} -{{- $repositoryName := .Values.metrics.image.repository -}} -{{- $tag := default "latest" .Values.metrics.image.tag | toString -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. -Also, we can't use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} - {{- if .Values.global.imageRegistry }} - {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} - {{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} - {{- end -}} -{{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} -{{- end -}} - -{{/* -Get the password secret. -*/}} -{{- define "postgresql.secretName" -}} -{{- if .Values.global.postgresql.existingSecret }} - {{- printf "%s" .Values.global.postgresql.existingSecret -}} -{{- else if .Values.existingSecret -}} - {{- printf "%s" .Values.existingSecret -}} -{{- else -}} - {{- printf "%s" (include "postgresql.fullname" .) -}} -{{- end -}} -{{- end -}} - -{{/* -Return true if a secret object should be created -*/}} -{{- define "postgresql.createSecret" -}} -{{- if .Values.global.postgresql.existingSecret }} -{{- else if .Values.existingSecret -}} -{{- else -}} - {{- true -}} -{{- end -}} -{{- end -}} - -{{/* -Get the configuration ConfigMap name. -*/}} -{{- define "postgresql.configurationCM" -}} -{{- if .Values.configurationConfigMap -}} -{{- printf "%s" (tpl .Values.configurationConfigMap $) -}} -{{- else -}} -{{- printf "%s-configuration" (include "postgresql.fullname" .) -}} -{{- end -}} -{{- end -}} - -{{/* -Get the extended configuration ConfigMap name. -*/}} -{{- define "postgresql.extendedConfigurationCM" -}} -{{- if .Values.extendedConfConfigMap -}} -{{- printf "%s" (tpl .Values.extendedConfConfigMap $) -}} -{{- else -}} -{{- printf "%s-extended-configuration" (include "postgresql.fullname" .) -}} -{{- end -}} -{{- end -}} - -{{/* -Get the initialization scripts ConfigMap name. -*/}} -{{- define "postgresql.initdbScriptsCM" -}} -{{- if .Values.initdbScriptsConfigMap -}} -{{- printf "%s" (tpl .Values.initdbScriptsConfigMap $) -}} -{{- else -}} -{{- printf "%s-init-scripts" (include "postgresql.fullname" .) -}} -{{- end -}} -{{- end -}} - -{{/* -Get the initialization scripts Secret name. -*/}} -{{- define "postgresql.initdbScriptsSecret" -}} -{{- printf "%s" (tpl .Values.initdbScriptsSecret $) -}} -{{- end -}} - -{{/* -Get the metrics ConfigMap name. -*/}} -{{- define "postgresql.metricsCM" -}} -{{- printf "%s-metrics" (include "postgresql.fullname" .) -}} -{{- end -}} - -{{/* -Return the proper Docker Image Registry Secret Names -*/}} -{{- define "postgresql.imagePullSecrets" -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. -Also, we can not use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} -{{- if .Values.global.imagePullSecrets }} -imagePullSecrets: -{{- range .Values.global.imagePullSecrets }} - - name: {{ . }} -{{- end }} -{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets .Values.volumePermissions.image.pullSecrets }} -imagePullSecrets: -{{- range .Values.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.metrics.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.volumePermissions.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- end -}} -{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets .Values.volumePermissions.image.pullSecrets }} -imagePullSecrets: -{{- range .Values.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.metrics.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.volumePermissions.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- end -}} -{{- end -}} - -{{/* -Get the readiness probe command -*/}} -{{- define "postgresql.readinessProbeCommand" -}} -- | -{{- if (include "postgresql.database" .) }} - exec pg_isready -U {{ include "postgresql.username" . | quote }} -d {{ (include "postgresql.database" .) | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} -{{- else }} - exec pg_isready -U {{ include "postgresql.username" . | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} -{{- end }} -{{- if contains "bitnami/" .Values.image.repository }} - [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ] -{{- end -}} -{{- end -}} - -{{/* -Return the proper Storage Class -*/}} -{{- define "postgresql.storageClass" -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. -*/}} -{{- if .Values.global -}} - {{- if .Values.global.storageClass -}} - {{- if (eq "-" .Values.global.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.global.storageClass -}} - {{- end -}} - {{- else -}} - {{- if .Values.persistence.storageClass -}} - {{- if (eq "-" .Values.persistence.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.persistence.storageClass -}} - {{- end -}} - {{- end -}} - {{- end -}} -{{- else -}} - {{- if .Values.persistence.storageClass -}} - {{- if (eq "-" .Values.persistence.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.persistence.storageClass -}} - {{- end -}} - {{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Renders a value that contains template. -Usage: -{{ include "postgresql.tplValue" ( dict "value" .Values.path.to.the.Value "context" $) }} -*/}} -{{- define "postgresql.tplValue" -}} - {{- if typeIs "string" .value }} - {{- tpl .value .context }} - {{- else }} - {{- tpl (.value | toYaml) .context }} - {{- end }} -{{- end -}} - -{{/* -Return the appropriate apiVersion for statefulset. -*/}} -{{- define "postgresql.statefulset.apiVersion" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "apps/v1beta2" -}} -{{- else -}} -{{- print "apps/v1" -}} -{{- end -}} -{{- end -}} - -{{/* -Compile all warnings into a single message, and call fail. -*/}} -{{- define "postgresql.validateValues" -}} -{{- $messages := list -}} -{{- $messages := append $messages (include "postgresql.validateValues.ldapConfigurationMethod" .) -}} -{{- $messages := without $messages "" -}} -{{- $message := join "\n" $messages -}} - -{{- if $message -}} -{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} -{{- end -}} -{{- end -}} - -{{/* -Validate values of Postgresql - If ldap.url is used then you don't need the other settings for ldap -*/}} -{{- define "postgresql.validateValues.ldapConfigurationMethod" -}} -{{- if and .Values.ldap.enabled (and (not (empty .Values.ldap.url)) (not (empty .Values.ldap.server))) }} -postgresql: ldap.url, ldap.server - You cannot set both `ldap.url` and `ldap.server` at the same time. - Please provide a unique way to configure LDAP. - More info at https://www.postgresql.org/docs/current/auth-ldap.html -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/postgresql/templates/configmap.yaml b/infra/charts/feast/charts/postgresql/templates/configmap.yaml deleted file mode 100644 index d2178c077e5..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/configmap.yaml +++ /dev/null @@ -1,26 +0,0 @@ -{{ if and (or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration) (not .Values.configurationConfigMap) }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "postgresql.fullname" . }}-configuration - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -data: -{{- if (.Files.Glob "files/postgresql.conf") }} -{{ (.Files.Glob "files/postgresql.conf").AsConfig | indent 2 }} -{{- else if .Values.postgresqlConfiguration }} - postgresql.conf: | -{{- range $key, $value := default dict .Values.postgresqlConfiguration }} - {{ $key | snakecase }}={{ $value }} -{{- end }} -{{- end }} -{{- if (.Files.Glob "files/pg_hba.conf") }} -{{ (.Files.Glob "files/pg_hba.conf").AsConfig | indent 2 }} -{{- else if .Values.pgHbaConfiguration }} - pg_hba.conf: | -{{ .Values.pgHbaConfiguration | indent 4 }} -{{- end }} -{{ end }} diff --git a/infra/charts/feast/charts/postgresql/templates/extended-config-configmap.yaml b/infra/charts/feast/charts/postgresql/templates/extended-config-configmap.yaml deleted file mode 100644 index 8a411957823..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/extended-config-configmap.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and (or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf) (not .Values.extendedConfConfigMap)}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "postgresql.fullname" . }}-extended-configuration - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -data: -{{- with .Files.Glob "files/conf.d/*.conf" }} -{{ .AsConfig | indent 2 }} -{{- end }} -{{ with .Values.postgresqlExtendedConf }} - override.conf: | -{{- range $key, $value := . }} - {{ $key | snakecase }}={{ $value }} -{{- end }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/initialization-configmap.yaml b/infra/charts/feast/charts/postgresql/templates/initialization-configmap.yaml deleted file mode 100644 index 8eb5e05881f..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/initialization-configmap.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if and (or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScripts) (not .Values.initdbScriptsConfigMap) }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "postgresql.fullname" . }}-init-scripts - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -{{- with .Files.Glob "files/docker-entrypoint-initdb.d/*.sql.gz" }} -binaryData: -{{- range $path, $bytes := . }} - {{ base $path }}: {{ $.Files.Get $path | b64enc | quote }} -{{- end }} -{{- end }} -data: -{{- with .Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql}" }} -{{ .AsConfig | indent 2 }} -{{- end }} -{{- with .Values.initdbScripts }} -{{ toYaml . | indent 2 }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/metrics-configmap.yaml b/infra/charts/feast/charts/postgresql/templates/metrics-configmap.yaml deleted file mode 100644 index 524aa2f6a94..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/metrics-configmap.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "postgresql.metricsCM" . }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -data: - custom-metrics.yaml: {{ toYaml .Values.metrics.customMetrics | quote }} -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/metrics-svc.yaml b/infra/charts/feast/charts/postgresql/templates/metrics-svc.yaml deleted file mode 100644 index c610f09aff8..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/metrics-svc.yaml +++ /dev/null @@ -1,26 +0,0 @@ -{{- if .Values.metrics.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "postgresql.fullname" . }}-metrics - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} - annotations: -{{ toYaml .Values.metrics.service.annotations | indent 4 }} -spec: - type: {{ .Values.metrics.service.type }} - {{- if and (eq .Values.metrics.service.type "LoadBalancer") .Values.metrics.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.metrics.service.loadBalancerIP }} - {{- end }} - ports: - - name: http-metrics - port: 9187 - targetPort: http-metrics - selector: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name }} - role: master -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/networkpolicy.yaml b/infra/charts/feast/charts/postgresql/templates/networkpolicy.yaml deleted file mode 100644 index ea1fc9b3a22..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/networkpolicy.yaml +++ /dev/null @@ -1,38 +0,0 @@ -{{- if .Values.networkPolicy.enabled }} -kind: NetworkPolicy -apiVersion: {{ template "postgresql.networkPolicy.apiVersion" . }} -metadata: - name: {{ template "postgresql.fullname" . }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -spec: - podSelector: - matchLabels: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} - ingress: - # Allow inbound connections - - ports: - - port: {{ template "postgresql.port" . }} - {{- if not .Values.networkPolicy.allowExternal }} - from: - - podSelector: - matchLabels: - {{ template "postgresql.fullname" . }}-client: "true" - {{- if .Values.networkPolicy.explicitNamespacesSelector }} - namespaceSelector: -{{ toYaml .Values.networkPolicy.explicitNamespacesSelector | indent 12 }} - {{- end }} - - podSelector: - matchLabels: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} - role: slave - {{- end }} - # Allow prometheus scrapes - - ports: - - port: 9187 -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/prometheusrule.yaml b/infra/charts/feast/charts/postgresql/templates/prometheusrule.yaml deleted file mode 100644 index 44f1242dddb..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/prometheusrule.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ template "postgresql.fullname" . }} -{{- with .Values.metrics.prometheusRule.namespace }} - namespace: {{ . }} -{{- end }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -{{- with .Values.metrics.prometheusRule.additionalLabels }} -{{ toYaml . | indent 4 }} -{{- end }} -spec: -{{- with .Values.metrics.prometheusRule.rules }} - groups: - - name: {{ template "postgresql.name" $ }} - rules: {{ tpl (toYaml .) $ | nindent 8 }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/secrets.yaml b/infra/charts/feast/charts/postgresql/templates/secrets.yaml deleted file mode 100644 index 094d18b49f8..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/secrets.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if (include "postgresql.createSecret" .) }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "postgresql.fullname" . }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -type: Opaque -data: - {{- if and .Values.postgresqlPostgresPassword (not (eq .Values.postgresqlUsername "postgres")) }} - postgresql-postgres-password: {{ include "postgresql.postgres.password" . | b64enc | quote }} - {{- end }} - postgresql-password: {{ include "postgresql.password" . | b64enc | quote }} - {{- if .Values.replication.enabled }} - postgresql-replication-password: {{ include "postgresql.replication.password" . | b64enc | quote }} - {{- end }} - {{- if (and .Values.ldap.enabled .Values.ldap.bind_password)}} - postgresql-ldap-password: {{ .Values.ldap.bind_password | b64enc | quote }} - {{- end }} -{{- end -}} diff --git a/infra/charts/feast/charts/postgresql/templates/serviceaccount.yaml b/infra/charts/feast/charts/postgresql/templates/serviceaccount.yaml deleted file mode 100644 index 27e5b516efa..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/serviceaccount.yaml +++ /dev/null @@ -1,11 +0,0 @@ -{{- if and (.Values.serviceAccount.enabled) (not .Values.serviceAccount.name) }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} - name: {{ template "postgresql.fullname" . }} -{{- end }} \ No newline at end of file diff --git a/infra/charts/feast/charts/postgresql/templates/servicemonitor.yaml b/infra/charts/feast/charts/postgresql/templates/servicemonitor.yaml deleted file mode 100644 index f3a529a9649..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/servicemonitor.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ include "postgresql.fullname" . }} - {{- if .Values.metrics.serviceMonitor.namespace }} - namespace: {{ .Values.metrics.serviceMonitor.namespace }} - {{- end }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} - {{- if .Values.metrics.serviceMonitor.additionalLabels }} -{{ toYaml .Values.metrics.serviceMonitor.additionalLabels | indent 4 }} - {{- end }} -spec: - endpoints: - - port: http-metrics - {{- if .Values.metrics.serviceMonitor.interval }} - interval: {{ .Values.metrics.serviceMonitor.interval }} - {{- end }} - {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} - {{- end }} - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} - selector: - matchLabels: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name }} -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/statefulset-slaves.yaml b/infra/charts/feast/charts/postgresql/templates/statefulset-slaves.yaml deleted file mode 100644 index 3290ff7fcd0..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/statefulset-slaves.yaml +++ /dev/null @@ -1,299 +0,0 @@ -{{- if .Values.replication.enabled }} -apiVersion: {{ template "postgresql.statefulset.apiVersion" . }} -kind: StatefulSet -metadata: - name: "{{ template "postgresql.fullname" . }}-slave" - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -{{- with .Values.slave.labels }} -{{ toYaml . | indent 4 }} -{{- end }} -{{- with .Values.slave.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: - serviceName: {{ template "postgresql.fullname" . }}-headless - replicas: {{ .Values.replication.slaveReplicas }} - selector: - matchLabels: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} - role: slave - template: - metadata: - name: {{ template "postgresql.fullname" . }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} - role: slave -{{- with .Values.slave.podLabels }} -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.slave.podAnnotations }} - annotations: -{{ toYaml . | indent 8 }} -{{- end }} - spec: - {{- if .Values.schedulerName }} - schedulerName: "{{ .Values.schedulerName }}" - {{- end }} -{{- include "postgresql.imagePullSecrets" . | indent 6 }} - {{- if .Values.slave.nodeSelector }} - nodeSelector: -{{ toYaml .Values.slave.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.slave.affinity }} - affinity: -{{ toYaml .Values.slave.affinity | indent 8 }} - {{- end }} - {{- if .Values.slave.tolerations }} - tolerations: -{{ toYaml .Values.slave.tolerations | indent 8 }} - {{- end }} - {{- if .Values.terminationGracePeriodSeconds }} - terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} - {{- end }} - {{- if .Values.securityContext.enabled }} - securityContext: - fsGroup: {{ .Values.securityContext.fsGroup }} - {{- end }} - {{- if .Values.serviceAccount.enabled }} - serviceAccountName: {{ default (include "postgresql.fullname" . ) .Values.serviceAccount.name}} - {{- end }} - {{- if or .Values.slave.extraInitContainers (and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled))) }} - initContainers: - {{- if and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled)) }} - - name: init-chmod-data - image: {{ template "postgresql.volumePermissions.image" . }} - imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} - {{- if .Values.resources }} - resources: {{- toYaml .Values.resources | nindent 12 }} - {{- end }} - command: - - /bin/sh - - -cx - - | - {{ if .Values.persistence.enabled }} - mkdir -p {{ .Values.persistence.mountPath }}/data - chmod 700 {{ .Values.persistence.mountPath }}/data - find {{ .Values.persistence.mountPath }} -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | \ - {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} - xargs chown -R `id -u`:`id -G | cut -d " " -f2` - {{- else }} - xargs chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} - {{- end }} - {{- end }} - {{- if and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled }} - chmod -R 777 /dev/shm - {{- end }} - {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} - securityContext: - {{- else }} - securityContext: - runAsUser: {{ .Values.volumePermissions.securityContext.runAsUser }} - {{- end }} - volumeMounts: - {{ if .Values.persistence.enabled }} - - name: data - mountPath: {{ .Values.persistence.mountPath }} - subPath: {{ .Values.persistence.subPath }} - {{- end }} - {{- if .Values.shmVolume.enabled }} - - name: dshm - mountPath: /dev/shm - {{- end }} - {{- end }} - {{- if .Values.slave.extraInitContainers }} -{{ tpl .Values.slave.extraInitContainers . | indent 8 }} - {{- end }} - {{- end }} - {{- if .Values.slave.priorityClassName }} - priorityClassName: {{ .Values.slave.priorityClassName }} - {{- end }} - containers: - - name: {{ template "postgresql.fullname" . }} - image: {{ template "postgresql.image" . }} - imagePullPolicy: "{{ .Values.image.pullPolicy }}" - {{- if .Values.resources }} - resources: {{- toYaml .Values.resources | nindent 12 }} - {{- end }} - {{- if .Values.securityContext.enabled }} - securityContext: - runAsUser: {{ .Values.securityContext.runAsUser }} - {{- end }} - env: - - name: BITNAMI_DEBUG - value: {{ ternary "true" "false" .Values.image.debug | quote }} - - name: POSTGRESQL_VOLUME_DIR - value: "{{ .Values.persistence.mountPath }}" - - name: POSTGRESQL_PORT_NUMBER - value: "{{ template "postgresql.port" . }}" - {{- if .Values.persistence.mountPath }} - - name: PGDATA - value: {{ .Values.postgresqlDataDir | quote }} - {{- end }} - - name: POSTGRES_REPLICATION_MODE - value: "slave" - - name: POSTGRES_REPLICATION_USER - value: {{ include "postgresql.replication.username" . | quote }} - {{- if .Values.usePasswordFile }} - - name: POSTGRES_REPLICATION_PASSWORD_FILE - value: "/opt/bitnami/postgresql/secrets/postgresql-replication-password" - {{- else }} - - name: POSTGRES_REPLICATION_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "postgresql.secretName" . }} - key: postgresql-replication-password - {{- end }} - - name: POSTGRES_CLUSTER_APP_NAME - value: {{ .Values.replication.applicationName }} - - name: POSTGRES_MASTER_HOST - value: {{ template "postgresql.fullname" . }} - - name: POSTGRES_MASTER_PORT_NUMBER - value: {{ include "postgresql.port" . | quote }} - {{- if and .Values.postgresqlPostgresPassword (not (eq .Values.postgresqlUsername "postgres")) }} - {{- if .Values.usePasswordFile }} - - name: POSTGRES_POSTGRES_PASSWORD_FILE - value: "/opt/bitnami/postgresql/secrets/postgresql-postgres-password" - {{- else }} - - name: POSTGRES_POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "postgresql.secretName" . }} - key: postgresql-postgres-password - {{- end }} - {{- end }} - {{- if .Values.usePasswordFile }} - - name: POSTGRES_PASSWORD_FILE - value: "/opt/bitnami/postgresql/secrets/postgresql-password" - {{- else }} - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "postgresql.secretName" . }} - key: postgresql-password - {{- end }} - ports: - - name: tcp-postgresql - containerPort: {{ template "postgresql.port" . }} - {{- if .Values.livenessProbe.enabled }} - livenessProbe: - exec: - command: - - /bin/sh - - -c - {{- if (include "postgresql.database" .) }} - - exec pg_isready -U {{ include "postgresql.username" . | quote }} -d {{ (include "postgresql.database" .) | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} - {{- else }} - - exec pg_isready -U {{ include "postgresql.username" . | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} - {{- end }} - initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.readinessProbe.enabled }} - readinessProbe: - exec: - command: - - /bin/sh - - -c - - -e - {{- include "postgresql.readinessProbeCommand" . | nindent 16 }} - initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.readinessProbe.failureThreshold }} - {{- end }} - volumeMounts: - {{- if .Values.usePasswordFile }} - - name: postgresql-password - mountPath: /opt/bitnami/postgresql/secrets/ - {{- end }} - {{- if .Values.shmVolume.enabled }} - - name: dshm - mountPath: /dev/shm - {{- end }} - {{- if .Values.persistence.enabled }} - - name: data - mountPath: {{ .Values.persistence.mountPath }} - subPath: {{ .Values.persistence.subPath }} - {{ end }} - {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} - - name: postgresql-extended-config - mountPath: /bitnami/postgresql/conf/conf.d/ - {{- end }} - {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} - - name: postgresql-config - mountPath: /bitnami/postgresql/conf - {{- end }} - {{- if .Values.slave.extraVolumeMounts }} - {{- toYaml .Values.slave.extraVolumeMounts | nindent 12 }} - {{- end }} -{{- if .Values.slave.sidecars }} -{{- include "postgresql.tplValue" ( dict "value" .Values.slave.sidecars "context" $ ) | nindent 8 }} -{{- end }} - volumes: - {{- if .Values.usePasswordFile }} - - name: postgresql-password - secret: - secretName: {{ template "postgresql.secretName" . }} - {{- end }} - {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap}} - - name: postgresql-config - configMap: - name: {{ template "postgresql.configurationCM" . }} - {{- end }} - {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} - - name: postgresql-extended-config - configMap: - name: {{ template "postgresql.extendedConfigurationCM" . }} - {{- end }} - {{- if .Values.shmVolume.enabled }} - - name: dshm - emptyDir: - medium: Memory - sizeLimit: 1Gi - {{- end }} - {{- if not .Values.persistence.enabled }} - - name: data - emptyDir: {} - {{- end }} - {{- if .Values.slave.extraVolumes }} - {{- toYaml .Values.slave.extraVolumes | nindent 8 }} - {{- end }} - updateStrategy: - type: {{ .Values.updateStrategy.type }} - {{- if (eq "Recreate" .Values.updateStrategy.type) }} - rollingUpdate: null - {{- end }} -{{- if .Values.persistence.enabled }} - volumeClaimTemplates: - - metadata: - name: data - {{- with .Values.persistence.annotations }} - annotations: - {{- range $key, $value := . }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - spec: - accessModes: - {{- range .Values.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} - {{ include "postgresql.storageClass" . }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/statefulset.yaml b/infra/charts/feast/charts/postgresql/templates/statefulset.yaml deleted file mode 100644 index 3390be22b2b..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/statefulset.yaml +++ /dev/null @@ -1,458 +0,0 @@ -apiVersion: {{ template "postgresql.statefulset.apiVersion" . }} -kind: StatefulSet -metadata: - name: {{ template "postgresql.master.fullname" . }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -{{- with .Values.master.labels }} -{{ toYaml . | indent 4 }} -{{- end }} -{{- with .Values.master.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: - serviceName: {{ template "postgresql.fullname" . }}-headless - replicas: 1 - updateStrategy: - type: {{ .Values.updateStrategy.type }} - {{- if (eq "Recreate" .Values.updateStrategy.type) }} - rollingUpdate: null - {{- end }} - selector: - matchLabels: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} - role: master - template: - metadata: - name: {{ template "postgresql.fullname" . }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} - role: master -{{- with .Values.master.podLabels }} -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.master.podAnnotations }} - annotations: -{{ toYaml . | indent 8 }} -{{- end }} - spec: - {{- if .Values.schedulerName }} - schedulerName: "{{ .Values.schedulerName }}" - {{- end }} -{{- include "postgresql.imagePullSecrets" . | indent 6 }} - {{- if .Values.master.nodeSelector }} - nodeSelector: -{{ toYaml .Values.master.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.master.affinity }} - affinity: -{{ toYaml .Values.master.affinity | indent 8 }} - {{- end }} - {{- if .Values.master.tolerations }} - tolerations: -{{ toYaml .Values.master.tolerations | indent 8 }} - {{- end }} - {{- if .Values.terminationGracePeriodSeconds }} - terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} - {{- end }} - {{- if .Values.securityContext.enabled }} - securityContext: - fsGroup: {{ .Values.securityContext.fsGroup }} - {{- end }} - {{- if .Values.serviceAccount.enabled }} - serviceAccountName: {{ default (include "postgresql.fullname" . ) .Values.serviceAccount.name }} - {{- end }} - {{- if or .Values.master.extraInitContainers (and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled))) }} - initContainers: - {{- if and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled)) }} - - name: init-chmod-data - image: {{ template "postgresql.volumePermissions.image" . }} - imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} - {{- if .Values.resources }} - resources: {{- toYaml .Values.resources | nindent 12 }} - {{- end }} - command: - - /bin/sh - - -cx - - | - {{ if .Values.persistence.enabled }} - mkdir -p {{ .Values.persistence.mountPath }}/data - chmod 700 {{ .Values.persistence.mountPath }}/data - find {{ .Values.persistence.mountPath }} -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | \ - {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} - xargs chown -R `id -u`:`id -G | cut -d " " -f2` - {{- else }} - xargs chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} - {{- end }} - {{- end }} - {{- if and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled }} - chmod -R 777 /dev/shm - {{- end }} - {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} - securityContext: - {{- else }} - securityContext: - runAsUser: {{ .Values.volumePermissions.securityContext.runAsUser }} - {{- end }} - volumeMounts: - {{ if .Values.persistence.enabled }} - - name: data - mountPath: {{ .Values.persistence.mountPath }} - subPath: {{ .Values.persistence.subPath }} - {{- end }} - {{- if .Values.shmVolume.enabled }} - - name: dshm - mountPath: /dev/shm - {{- end }} - {{- end }} - {{- if .Values.master.extraInitContainers }} -{{ tpl .Values.master.extraInitContainers . | indent 8 }} - {{- end }} - {{- end }} - {{- if .Values.master.priorityClassName }} - priorityClassName: {{ .Values.master.priorityClassName }} - {{- end }} - containers: - - name: {{ template "postgresql.fullname" . }} - image: {{ template "postgresql.image" . }} - imagePullPolicy: "{{ .Values.image.pullPolicy }}" - {{- if .Values.resources }} - resources: {{- toYaml .Values.resources | nindent 12 }} - {{- end }} - {{- if .Values.securityContext.enabled }} - securityContext: - runAsUser: {{ .Values.securityContext.runAsUser }} - {{- end }} - env: - - name: BITNAMI_DEBUG - value: {{ ternary "true" "false" .Values.image.debug | quote }} - - name: POSTGRESQL_PORT_NUMBER - value: "{{ template "postgresql.port" . }}" - - name: POSTGRESQL_VOLUME_DIR - value: "{{ .Values.persistence.mountPath }}" - {{- if .Values.postgresqlInitdbArgs }} - - name: POSTGRES_INITDB_ARGS - value: {{ .Values.postgresqlInitdbArgs | quote }} - {{- end }} - {{- if .Values.postgresqlInitdbWalDir }} - - name: POSTGRES_INITDB_WALDIR - value: {{ .Values.postgresqlInitdbWalDir | quote }} - {{- end }} - {{- if .Values.initdbUser }} - - name: POSTGRESQL_INITSCRIPTS_USERNAME - value: {{ .Values.initdbUser }} - {{- end }} - {{- if .Values.initdbPassword }} - - name: POSTGRESQL_INITSCRIPTS_PASSWORD - value: .Values.initdbPassword - {{- end }} - {{- if .Values.persistence.mountPath }} - - name: PGDATA - value: {{ .Values.postgresqlDataDir | quote }} - {{- end }} - {{- if .Values.replication.enabled }} - - name: POSTGRES_REPLICATION_MODE - value: "master" - - name: POSTGRES_REPLICATION_USER - value: {{ include "postgresql.replication.username" . | quote }} - {{- if .Values.usePasswordFile }} - - name: POSTGRES_REPLICATION_PASSWORD_FILE - value: "/opt/bitnami/postgresql/secrets/postgresql-replication-password" - {{- else }} - - name: POSTGRES_REPLICATION_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "postgresql.secretName" . }} - key: postgresql-replication-password - {{- end }} - {{- if not (eq .Values.replication.synchronousCommit "off")}} - - name: POSTGRES_SYNCHRONOUS_COMMIT_MODE - value: {{ .Values.replication.synchronousCommit | quote }} - - name: POSTGRES_NUM_SYNCHRONOUS_REPLICAS - value: {{ .Values.replication.numSynchronousReplicas | quote }} - {{- end }} - - name: POSTGRES_CLUSTER_APP_NAME - value: {{ .Values.replication.applicationName }} - {{- end }} - {{- if and .Values.postgresqlPostgresPassword (not (eq .Values.postgresqlUsername "postgres")) }} - {{- if .Values.usePasswordFile }} - - name: POSTGRES_POSTGRES_PASSWORD_FILE - value: "/opt/bitnami/postgresql/secrets/postgresql-postgres-password" - {{- else }} - - name: POSTGRES_POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "postgresql.secretName" . }} - key: postgresql-postgres-password - {{- end }} - {{- end }} - - name: POSTGRES_USER - value: {{ include "postgresql.username" . | quote }} - {{- if .Values.usePasswordFile }} - - name: POSTGRES_PASSWORD_FILE - value: "/opt/bitnami/postgresql/secrets/postgresql-password" - {{- else }} - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "postgresql.secretName" . }} - key: postgresql-password - {{- end }} - {{- if (include "postgresql.database" .) }} - - name: POSTGRES_DB - value: {{ (include "postgresql.database" .) | quote }} - {{- end }} - {{- if .Values.extraEnv }} - {{- include "postgresql.tplValue" (dict "value" .Values.extraEnv "context" $) | nindent 12 }} - {{- end }} - - name: POSTGRESQL_ENABLE_LDAP - value: {{ ternary "yes" "no" .Values.ldap.enabled | quote }} - {{- if .Values.ldap.enabled }} - - name: POSTGRESQL_LDAP_SERVER - value: {{ .Values.ldap.server }} - - name: POSTGRESQL_LDAP_PORT - value: {{ .Values.ldap.port | quote }} - - name: POSTGRESQL_LDAP_SCHEME - value: {{ .Values.ldap.scheme }} - {{- if .Values.ldap.tls }} - - name: POSTGRESQL_LDAP_TLS - value: "1" - {{- end}} - - name: POSTGRESQL_LDAP_PREFIX - value: {{ .Values.ldap.prefix | quote }} - - name: POSTGRESQL_LDAP_SUFFIX - value: {{ .Values.ldap.suffix | quote}} - - name: POSTGRESQL_LDAP_BASE_DN - value: {{ .Values.ldap.baseDN }} - - name: POSTGRESQL_LDAP_BIND_DN - value: {{ .Values.ldap.bindDN }} - {{- if (not (empty .Values.ldap.bind_password)) }} - - name: POSTGRESQL_LDAP_BIND_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "postgresql.secretName" . }} - key: postgresql-ldap-password - {{- end}} - - name: POSTGRESQL_LDAP_SEARCH_ATTR - value: {{ .Values.ldap.search_attr }} - - name: POSTGRESQL_LDAP_SEARCH_FILTER - value: {{ .Values.ldap.search_filter }} - - name: POSTGRESQL_LDAP_URL - value: {{ .Values.ldap.url }} - {{- end}} - {{- if .Values.extraEnvVarsCM }} - envFrom: - - configMapRef: - name: {{ .Values.extraEnvVarsCM }} - {{- end }} - ports: - - name: tcp-postgresql - containerPort: {{ template "postgresql.port" . }} - {{- if .Values.livenessProbe.enabled }} - livenessProbe: - exec: - command: - - /bin/sh - - -c - {{- if (include "postgresql.database" .) }} - - exec pg_isready -U {{ include "postgresql.username" . | quote }} -d {{ (include "postgresql.database" .) | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} - {{- else }} - - exec pg_isready -U {{ include "postgresql.username" . | quote }} -h 127.0.0.1 -p {{ template "postgresql.port" . }} - {{- end }} - initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.readinessProbe.enabled }} - readinessProbe: - exec: - command: - - /bin/sh - - -c - - -e - {{- include "postgresql.readinessProbeCommand" . | nindent 16 }} - initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.readinessProbe.failureThreshold }} - {{- end }} - volumeMounts: - {{- if or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScriptsConfigMap .Values.initdbScripts }} - - name: custom-init-scripts - mountPath: /docker-entrypoint-initdb.d/ - {{- end }} - {{- if .Values.initdbScriptsSecret }} - - name: custom-init-scripts-secret - mountPath: /docker-entrypoint-initdb.d/secret - {{- end }} - {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} - - name: postgresql-extended-config - mountPath: /bitnami/postgresql/conf/conf.d/ - {{- end }} - {{- if .Values.usePasswordFile }} - - name: postgresql-password - mountPath: /opt/bitnami/postgresql/secrets/ - {{- end }} - {{- if .Values.shmVolume.enabled }} - - name: dshm - mountPath: /dev/shm - {{- end }} - {{- if .Values.persistence.enabled }} - - name: data - mountPath: {{ .Values.persistence.mountPath }} - subPath: {{ .Values.persistence.subPath }} - {{- end }} - {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} - - name: postgresql-config - mountPath: /bitnami/postgresql/conf - {{- end }} - {{- if .Values.master.extraVolumeMounts }} - {{- toYaml .Values.master.extraVolumeMounts | nindent 12 }} - {{- end }} -{{- if .Values.master.sidecars }} -{{- include "postgresql.tplValue" ( dict "value" .Values.master.sidecars "context" $ ) | nindent 8 }} -{{- end }} -{{- if .Values.metrics.enabled }} - - name: metrics - image: {{ template "postgresql.metrics.image" . }} - imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} - {{- if .Values.metrics.securityContext.enabled }} - securityContext: - runAsUser: {{ .Values.metrics.securityContext.runAsUser }} - {{- end }} - env: - {{- $database := required "In order to enable metrics you need to specify a database (.Values.postgresqlDatabase or .Values.global.postgresql.postgresqlDatabase)" (include "postgresql.database" .) }} - - name: DATA_SOURCE_URI - value: {{ printf "127.0.0.1:%d/%s?sslmode=disable" (int (include "postgresql.port" .)) $database | quote }} - {{- if .Values.usePasswordFile }} - - name: DATA_SOURCE_PASS_FILE - value: "/opt/bitnami/postgresql/secrets/postgresql-password" - {{- else }} - - name: DATA_SOURCE_PASS - valueFrom: - secretKeyRef: - name: {{ template "postgresql.secretName" . }} - key: postgresql-password - {{- end }} - - name: DATA_SOURCE_USER - value: {{ template "postgresql.username" . }} - {{- if .Values.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: / - port: http-metrics - initialDelaySeconds: {{ .Values.metrics.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.metrics.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.metrics.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.metrics.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.metrics.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: / - port: http-metrics - initialDelaySeconds: {{ .Values.metrics.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.metrics.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.metrics.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.metrics.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.metrics.readinessProbe.failureThreshold }} - {{- end }} - volumeMounts: - {{- if .Values.usePasswordFile }} - - name: postgresql-password - mountPath: /opt/bitnami/postgresql/secrets/ - {{- end }} - {{- if .Values.metrics.customMetrics }} - - name: custom-metrics - mountPath: /conf - readOnly: true - args: ["--extend.query-path", "/conf/custom-metrics.yaml"] - {{- end }} - ports: - - name: http-metrics - containerPort: 9187 - {{- if .Values.metrics.resources }} - resources: {{- toYaml .Values.metrics.resources | nindent 12 }} - {{- end }} -{{- end }} - volumes: - {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap}} - - name: postgresql-config - configMap: - name: {{ template "postgresql.configurationCM" . }} - {{- end }} - {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} - - name: postgresql-extended-config - configMap: - name: {{ template "postgresql.extendedConfigurationCM" . }} - {{- end }} - {{- if .Values.usePasswordFile }} - - name: postgresql-password - secret: - secretName: {{ template "postgresql.secretName" . }} - {{- end }} - {{- if or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScriptsConfigMap .Values.initdbScripts }} - - name: custom-init-scripts - configMap: - name: {{ template "postgresql.initdbScriptsCM" . }} - {{- end }} - {{- if .Values.initdbScriptsSecret }} - - name: custom-init-scripts-secret - secret: - secretName: {{ template "postgresql.initdbScriptsSecret" . }} - {{- end }} - {{- if .Values.master.extraVolumes }} - {{- toYaml .Values.master.extraVolumes | nindent 8 }} - {{- end }} - {{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} - - name: custom-metrics - configMap: - name: {{ template "postgresql.metricsCM" . }} - {{- end }} - {{- if .Values.shmVolume.enabled }} - - name: dshm - emptyDir: - medium: Memory - sizeLimit: 1Gi - {{- end }} -{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }} - - name: data - persistentVolumeClaim: -{{- with .Values.persistence.existingClaim }} - claimName: {{ tpl . $ }} -{{- end }} -{{- else if not .Values.persistence.enabled }} - - name: data - emptyDir: {} -{{- else if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} - volumeClaimTemplates: - - metadata: - name: data - {{- with .Values.persistence.annotations }} - annotations: - {{- range $key, $value := . }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - spec: - accessModes: - {{- range .Values.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} - {{ include "postgresql.storageClass" . }} -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/svc-headless.yaml b/infra/charts/feast/charts/postgresql/templates/svc-headless.yaml deleted file mode 100644 index 5c71f468d82..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/svc-headless.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "postgresql.fullname" . }}-headless - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -spec: - type: ClusterIP - clusterIP: None - ports: - - name: tcp-postgresql - port: {{ template "postgresql.port" . }} - targetPort: tcp-postgresql - selector: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} diff --git a/infra/charts/feast/charts/postgresql/templates/svc-read.yaml b/infra/charts/feast/charts/postgresql/templates/svc-read.yaml deleted file mode 100644 index d9492e2ff3e..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/svc-read.yaml +++ /dev/null @@ -1,31 +0,0 @@ -{{- if .Values.replication.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "postgresql.fullname" . }}-read - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -{{- with .Values.service.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: - type: {{ .Values.service.type }} - {{- if and .Values.service.loadBalancerIP (eq .Values.service.type "LoadBalancer") }} - loadBalancerIP: {{ .Values.service.loadBalancerIP }} - {{- end }} - ports: - - name: tcp-postgresql - port: {{ template "postgresql.port" . }} - targetPort: tcp-postgresql - {{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} - selector: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} - role: slave -{{- end }} diff --git a/infra/charts/feast/charts/postgresql/templates/svc.yaml b/infra/charts/feast/charts/postgresql/templates/svc.yaml deleted file mode 100644 index 0baea4ac84a..00000000000 --- a/infra/charts/feast/charts/postgresql/templates/svc.yaml +++ /dev/null @@ -1,38 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "postgresql.fullname" . }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -{{- with .Values.service.annotations }} - annotations: -{{ tpl (toYaml .) $ | indent 4 }} -{{- end }} -spec: - type: {{ .Values.service.type }} - {{- if and .Values.service.loadBalancerIP (eq .Values.service.type "LoadBalancer") }} - loadBalancerIP: {{ .Values.service.loadBalancerIP }} - {{- end }} - {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{ with .Values.service.loadBalancerSourceRanges }} -{{ toYaml . | indent 4 }} -{{- end }} - {{- end }} - {{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} - clusterIP: {{ .Values.service.clusterIP }} - {{- end }} - ports: - - name: tcp-postgresql - port: {{ template "postgresql.port" . }} - targetPort: tcp-postgresql - {{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} - selector: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} - role: master diff --git a/infra/charts/feast/charts/postgresql/values-production.yaml b/infra/charts/feast/charts/postgresql/values-production.yaml deleted file mode 100644 index 8da0b3d93fb..00000000000 --- a/infra/charts/feast/charts/postgresql/values-production.yaml +++ /dev/null @@ -1,520 +0,0 @@ -## Global Docker image parameters -## Please, note that this will override the image parameters, including dependencies, configured to use the global value -## Current available global Docker image parameters: imageRegistry and imagePullSecrets -## -global: - postgresql: {} -# imageRegistry: myRegistryName -# imagePullSecrets: -# - myRegistryKeySecretName -# storageClass: myStorageClass - -## Bitnami PostgreSQL image version -## ref: https://hub.docker.com/r/bitnami/postgresql/tags/ -## -image: - registry: docker.io - repository: bitnami/postgresql - tag: 11.7.0-debian-10-r9 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - - ## Set to true if you would like to see extra information on logs - ## It turns BASH and NAMI debugging in minideb - ## ref: https://github.com/bitnami/minideb-extras/#turn-on-bash-debugging - debug: false - -## String to partially override postgresql.fullname template (will maintain the release name) -## -# nameOverride: - -## String to fully override postgresql.fullname template -## -# fullnameOverride: - -## -## Init containers parameters: -## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup -## -volumePermissions: - enabled: false - image: - registry: docker.io - repository: bitnami/minideb - tag: buster - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - ## Init container Security Context - ## Note: the chown of the data folder is done to securityContext.runAsUser - ## and not the below volumePermissions.securityContext.runAsUser - ## When runAsUser is set to special value "auto", init container will try to chwon the - ## data folder to autodetermined user&group, using commands: `id -u`:`id -G | cut -d" " -f2` - ## "auto" is especially useful for OpenShift which has scc with dynamic userids (and 0 is not allowed). - ## You may want to use this volumePermissions.securityContext.runAsUser="auto" in combination with - ## pod securityContext.enabled=false and shmVolume.chmod.enabled=false - ## - securityContext: - runAsUser: 0 - -## Use an alternate scheduler, e.g. "stork". -## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ -## -# schedulerName: - -## Pod Security Context -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ -## -securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - -## Pod Service Account -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ -serviceAccount: - enabled: false - ## Name of an already existing service account. Setting this value disables the automatic service account creation. - # name: - -replication: - enabled: true - user: repl_user - password: repl_password - slaveReplicas: 2 - ## Set synchronous commit mode: on, off, remote_apply, remote_write and local - ## ref: https://www.postgresql.org/docs/9.6/runtime-config-wal.html#GUC-WAL-LEVEL - synchronousCommit: "on" - ## From the number of `slaveReplicas` defined above, set the number of those that will have synchronous replication - ## NOTE: It cannot be > slaveReplicas - numSynchronousReplicas: 1 - ## Replication Cluster application name. Useful for defining multiple replication policies - applicationName: my_application - -## PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`) -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-user-on-first-run (see note!) -# postgresqlPostgresPassword: - -## PostgreSQL user (has superuser privileges if username is `postgres`) -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run -postgresqlUsername: postgres - -## PostgreSQL password -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run -## -# postgresqlPassword: - -## PostgreSQL password using existing secret -## existingSecret: secret - -## Mount PostgreSQL secret as a file instead of passing environment variable -# usePasswordFile: false - -## Create a database -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-on-first-run -## -# postgresqlDatabase: - -## PostgreSQL data dir -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md -## -postgresqlDataDir: /bitnami/postgresql/data - -## An array to add extra environment variables -## For example: -## extraEnv: -## - name: FOO -## value: "bar" -## -# extraEnv: -extraEnv: [] - -## Name of a ConfigMap containing extra env vars -## -# extraEnvVarsCM: - -## Specify extra initdb args -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md -## -# postgresqlInitdbArgs: - -## Specify a custom location for the PostgreSQL transaction log -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md -## -# postgresqlInitdbWalDir: - -## PostgreSQL configuration -## Specify runtime configuration parameters as a dict, using camelCase, e.g. -## {"sharedBuffers": "500MB"} -## Alternatively, you can put your postgresql.conf under the files/ directory -## ref: https://www.postgresql.org/docs/current/static/runtime-config.html -## -# postgresqlConfiguration: - -## PostgreSQL extended configuration -## As above, but _appended_ to the main configuration -## Alternatively, you can put your *.conf under the files/conf.d/ directory -## https://github.com/bitnami/bitnami-docker-postgresql#allow-settings-to-be-loaded-from-files-other-than-the-default-postgresqlconf -## -# postgresqlExtendedConf: - -## PostgreSQL client authentication configuration -## Specify content for pg_hba.conf -## Default: do not create pg_hba.conf -## Alternatively, you can put your pg_hba.conf under the files/ directory -# pgHbaConfiguration: |- -# local all all trust -# host all all localhost trust -# host mydatabase mysuser 192.168.0.0/24 md5 - -## ConfigMap with PostgreSQL configuration -## NOTE: This will override postgresqlConfiguration and pgHbaConfiguration -# configurationConfigMap: - -## ConfigMap with PostgreSQL extended configuration -# extendedConfConfigMap: - -## initdb scripts -## Specify dictionary of scripts to be run at first boot -## Alternatively, you can put your scripts under the files/docker-entrypoint-initdb.d directory -## -# initdbScripts: -# my_init_script.sh: | -# #!/bin/sh -# echo "Do something." - -## Specify the PostgreSQL username and password to execute the initdb scripts -# initdbUser: -# initdbPassword: - -## ConfigMap with scripts to be run at first boot -## NOTE: This will override initdbScripts -# initdbScriptsConfigMap: - -## Secret with scripts to be run at first boot (in case it contains sensitive information) -## NOTE: This can work along initdbScripts or initdbScriptsConfigMap -# initdbScriptsSecret: - -## Optional duration in seconds the pod needs to terminate gracefully. -## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods -## -# terminationGracePeriodSeconds: 30 - -## LDAP configuration -## -ldap: - enabled: false - url: "" - server: "" - port: "" - prefix: "" - suffix: "" - baseDN: "" - bindDN: "" - bind_password: - search_attr: "" - search_filter: "" - scheme: "" - tls: false - -## PostgreSQL service configuration -service: - ## PosgresSQL service type - type: ClusterIP - # clusterIP: None - port: 5432 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. - ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart - annotations: {} - ## Set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - # loadBalancerIP: - - ## Load Balancer sources - ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service - ## - # loadBalancerSourceRanges: - # - 10.10.10.0/24 - -## Start master and slave(s) pod(s) without limitations on shm memory. -## By default docker and containerd (and possibly other container runtimes) -## limit `/dev/shm` to `64M` (see e.g. the -## [docker issue](https://github.com/docker-library/postgres/issues/416) and the -## [containerd issue](https://github.com/containerd/containerd/issues/3654), -## which could be not enough if PostgreSQL uses parallel workers heavily. -## -shmVolume: - ## Set `shmVolume.enabled` to `true` to mount a new tmpfs volume to remove - ## this limitation. - ## - enabled: true - ## Set to `true` to `chmod 777 /dev/shm` on a initContainer. - ## This option is ingored if `volumePermissions.enabled` is `false` - ## - chmod: - enabled: true - -## PostgreSQL data Persistent Volume Storage Class -## If defined, storageClassName: -## If set to "-", storageClassName: "", which disables dynamic provisioning -## If undefined (the default) or set to null, no storageClassName spec is -## set, choosing the default provisioner. (gp2 on AWS, standard on -## GKE, AWS & OpenStack) -## -persistence: - enabled: true - ## A manually managed Persistent Volume and Claim - ## If defined, PVC must be created manually before volume will be bound - ## The value is evaluated as a template, so, for example, the name can depend on .Release or .Chart - ## - # existingClaim: - - ## The path the volume will be mounted at, useful when using different - ## PostgreSQL images. - ## - mountPath: /bitnami/postgresql - - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - ## - subPath: "" - - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - annotations: {} - -## updateStrategy for PostgreSQL StatefulSet and its slaves StatefulSets -## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies -updateStrategy: - type: RollingUpdate - -## -## PostgreSQL Master parameters -## -master: - ## Node, affinity, tolerations, and priorityclass settings for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption - nodeSelector: {} - affinity: {} - tolerations: [] - labels: {} - annotations: {} - podLabels: {} - podAnnotations: {} - priorityClassName: "" - ## Additional PostgreSQL Master Volume mounts - ## - extraVolumeMounts: [] - ## Additional PostgreSQL Master Volumes - ## - extraVolumes: [] - ## Add sidecars to the pod - ## - ## For example: - ## sidecars: - ## - name: your-image-name - ## image: your-image - ## imagePullPolicy: Always - ## ports: - ## - name: portname - ## containerPort: 1234 - sidecars: [] - -## -## PostgreSQL Slave parameters -## -slave: - ## Node, affinity, tolerations, and priorityclass settings for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption - nodeSelector: {} - affinity: {} - tolerations: [] - labels: {} - annotations: {} - podLabels: {} - podAnnotations: {} - priorityClassName: "" - extraInitContainers: | - # - name: do-something - # image: busybox - # command: ['do', 'something'] - ## Additional PostgreSQL Slave Volume mounts - ## - extraVolumeMounts: [] - ## Additional PostgreSQL Slave Volumes - ## - extraVolumes: [] - ## Add sidecars to the pod - ## - ## For example: - ## sidecars: - ## - name: your-image-name - ## image: your-image - ## imagePullPolicy: Always - ## ports: - ## - name: portname - ## containerPort: 1234 - sidecars: [] - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -## -resources: - requests: - memory: 256Mi - cpu: 250m - -networkPolicy: - ## Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. - ## - enabled: false - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port PostgreSQL is listening - ## on. When true, PostgreSQL will accept connections from any source - ## (with the correct destination port). - ## - allowExternal: true - - ## 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 DB. - ## But sometimes, we want the DB 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. - ## - # explicitNamespacesSelector: - # matchLabels: - # role: frontend - # matchExpressions: - # - {key: role, operator: In, values: [frontend]} - -## Configure extra options for liveness and readiness probes -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) -livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - -readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - -## Configure metrics exporter -## -metrics: - enabled: true - # resources: {} - service: - type: ClusterIP - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "9187" - loadBalancerIP: - serviceMonitor: - enabled: false - additionalLabels: {} - # namespace: monitoring - # interval: 30s - # scrapeTimeout: 10s - ## Custom PrometheusRule to be defined - ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart - ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions - prometheusRule: - enabled: false - additionalLabels: {} - namespace: "" - rules: [] - ## These are just examples rules, please adapt them to your needs. - ## Make sure to constraint the rules to the current postgresql service. - # - alert: HugeReplicationLag - # expr: pg_replication_lag{service="{{ template "postgresql.fullname" . }}-metrics"} / 3600 > 1 - # for: 1m - # labels: - # severity: critical - # annotations: - # description: replication for {{ template "postgresql.fullname" . }} PostgreSQL is lagging by {{ "{{ $value }}" }} hour(s). - # summary: PostgreSQL replication is lagging by {{ "{{ $value }}" }} hour(s). - image: - registry: docker.io - repository: bitnami/postgres-exporter - tag: 0.8.0-debian-10-r28 - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - ## Define additional custom metrics - ## ref: https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file - # customMetrics: - # pg_database: - # query: "SELECT d.datname AS name, CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT') THEN pg_catalog.pg_database_size(d.datname) ELSE 0 END AS size FROM pg_catalog.pg_database d where datname not in ('template0', 'template1', 'postgres')" - # metrics: - # - name: - # usage: "LABEL" - # description: "Name of the database" - # - size_bytes: - # usage: "GAUGE" - # description: "Size of the database in bytes" - ## Pod Security Context - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - ## - securityContext: - enabled: false - runAsUser: 1001 - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## Configure extra options for liveness and readiness probes - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 diff --git a/infra/charts/feast/charts/postgresql/values.schema.json b/infra/charts/feast/charts/postgresql/values.schema.json deleted file mode 100644 index ac2de6e9432..00000000000 --- a/infra/charts/feast/charts/postgresql/values.schema.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema#", - "type": "object", - "properties": { - "postgresqlUsername": { - "type": "string", - "title": "Admin user", - "form": true - }, - "postgresqlPassword": { - "type": "string", - "title": "Password", - "form": true - }, - "persistence": { - "type": "object", - "properties": { - "size": { - "type": "string", - "title": "Persistent Volume Size", - "form": true, - "render": "slider", - "sliderMin": 1, - "sliderMax": 100, - "sliderUnit": "Gi" - } - } - }, - "resources": { - "type": "object", - "title": "Required Resources", - "description": "Configure resource requests", - "form": true, - "properties": { - "requests": { - "type": "object", - "properties": { - "memory": { - "type": "string", - "form": true, - "render": "slider", - "title": "Memory Request", - "sliderMin": 10, - "sliderMax": 2048, - "sliderUnit": "Mi" - }, - "cpu": { - "type": "string", - "form": true, - "render": "slider", - "title": "CPU Request", - "sliderMin": 10, - "sliderMax": 2000, - "sliderUnit": "m" - } - } - } - } - }, - "replication": { - "type": "object", - "form": true, - "title": "Replication Details", - "properties": { - "enabled": { - "type": "boolean", - "title": "Enable Replication", - "form": true - }, - "slaveReplicas": { - "type": "integer", - "title": "Slave Replicas", - "form": true, - "hidden": { - "condition": false, - "value": "replication.enabled" - } - } - } - }, - "volumePermissions": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable Init Containers", - "description": "Change the owner of the persist volume mountpoint to RunAsUser:fsGroup" - } - } - }, - "metrics": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "Configure metrics exporter", - "form": true - } - } - } - } -} diff --git a/infra/charts/feast/charts/postgresql/values.yaml b/infra/charts/feast/charts/postgresql/values.yaml deleted file mode 100644 index d336ea03892..00000000000 --- a/infra/charts/feast/charts/postgresql/values.yaml +++ /dev/null @@ -1,526 +0,0 @@ -## Global Docker image parameters -## Please, note that this will override the image parameters, including dependencies, configured to use the global value -## Current available global Docker image parameters: imageRegistry and imagePullSecrets -## -global: - postgresql: {} -# imageRegistry: myRegistryName -# imagePullSecrets: -# - myRegistryKeySecretName -# storageClass: myStorageClass - -## Bitnami PostgreSQL image version -## ref: https://hub.docker.com/r/bitnami/postgresql/tags/ -## -image: - registry: docker.io - repository: bitnami/postgresql - tag: 11.7.0-debian-10-r9 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - - ## Set to true if you would like to see extra information on logs - ## It turns BASH and NAMI debugging in minideb - ## ref: https://github.com/bitnami/minideb-extras/#turn-on-bash-debugging - debug: false - -## String to partially override postgresql.fullname template (will maintain the release name) -## -# nameOverride: - -## String to fully override postgresql.fullname template -## -# fullnameOverride: - -## -## Init containers parameters: -## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup -## -volumePermissions: - enabled: false - image: - registry: docker.io - repository: bitnami/minideb - tag: buster - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - ## Init container Security Context - ## Note: the chown of the data folder is done to securityContext.runAsUser - ## and not the below volumePermissions.securityContext.runAsUser - ## When runAsUser is set to special value "auto", init container will try to chwon the - ## data folder to autodetermined user&group, using commands: `id -u`:`id -G | cut -d" " -f2` - ## "auto" is especially useful for OpenShift which has scc with dynamic userids (and 0 is not allowed). - ## You may want to use this volumePermissions.securityContext.runAsUser="auto" in combination with - ## pod securityContext.enabled=false and shmVolume.chmod.enabled=false - ## - securityContext: - runAsUser: 0 - -## Use an alternate scheduler, e.g. "stork". -## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ -## -# schedulerName: - - -## Pod Security Context -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ -## -securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - -## Pod Service Account -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ -serviceAccount: - enabled: false - ## Name of an already existing service account. Setting this value disables the automatic service account creation. - # name: - -replication: - enabled: false - user: repl_user - password: repl_password - slaveReplicas: 1 - ## Set synchronous commit mode: on, off, remote_apply, remote_write and local - ## ref: https://www.postgresql.org/docs/9.6/runtime-config-wal.html#GUC-WAL-LEVEL - synchronousCommit: "off" - ## From the number of `slaveReplicas` defined above, set the number of those that will have synchronous replication - ## NOTE: It cannot be > slaveReplicas - numSynchronousReplicas: 0 - ## Replication Cluster application name. Useful for defining multiple replication policies - applicationName: my_application - -## PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`) -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-user-on-first-run (see note!) -# postgresqlPostgresPassword: - -## PostgreSQL user (has superuser privileges if username is `postgres`) -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run -postgresqlUsername: postgres - -## PostgreSQL password -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run -## -# postgresqlPassword: - -## PostgreSQL password using existing secret -## existingSecret: secret - -## Mount PostgreSQL secret as a file instead of passing environment variable -# usePasswordFile: false - -## Create a database -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-on-first-run -## -# postgresqlDatabase: - -## PostgreSQL data dir -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md -## -postgresqlDataDir: /bitnami/postgresql/data - -## An array to add extra environment variables -## For example: -## extraEnv: -## - name: FOO -## value: "bar" -## -# extraEnv: -extraEnv: [] - -## Name of a ConfigMap containing extra env vars -## -# extraEnvVarsCM: - -## Specify extra initdb args -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md -## -# postgresqlInitdbArgs: - -## Specify a custom location for the PostgreSQL transaction log -## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md -## -# postgresqlInitdbWalDir: - -## PostgreSQL configuration -## Specify runtime configuration parameters as a dict, using camelCase, e.g. -## {"sharedBuffers": "500MB"} -## Alternatively, you can put your postgresql.conf under the files/ directory -## ref: https://www.postgresql.org/docs/current/static/runtime-config.html -## -# postgresqlConfiguration: - -## PostgreSQL extended configuration -## As above, but _appended_ to the main configuration -## Alternatively, you can put your *.conf under the files/conf.d/ directory -## https://github.com/bitnami/bitnami-docker-postgresql#allow-settings-to-be-loaded-from-files-other-than-the-default-postgresqlconf -## -# postgresqlExtendedConf: - -## PostgreSQL client authentication configuration -## Specify content for pg_hba.conf -## Default: do not create pg_hba.conf -## Alternatively, you can put your pg_hba.conf under the files/ directory -# pgHbaConfiguration: |- -# local all all trust -# host all all localhost trust -# host mydatabase mysuser 192.168.0.0/24 md5 - -## ConfigMap with PostgreSQL configuration -## NOTE: This will override postgresqlConfiguration and pgHbaConfiguration -# configurationConfigMap: - -## ConfigMap with PostgreSQL extended configuration -# extendedConfConfigMap: - -## initdb scripts -## Specify dictionary of scripts to be run at first boot -## Alternatively, you can put your scripts under the files/docker-entrypoint-initdb.d directory -## -# initdbScripts: -# my_init_script.sh: | -# #!/bin/sh -# echo "Do something." - -## ConfigMap with scripts to be run at first boot -## NOTE: This will override initdbScripts -# initdbScriptsConfigMap: - -## Secret with scripts to be run at first boot (in case it contains sensitive information) -## NOTE: This can work along initdbScripts or initdbScriptsConfigMap -# initdbScriptsSecret: - -## Specify the PostgreSQL username and password to execute the initdb scripts -# initdbUser: -# initdbPassword: - -## Optional duration in seconds the pod needs to terminate gracefully. -## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods -## -# terminationGracePeriodSeconds: 30 - -## LDAP configuration -## -ldap: - enabled: false - url: "" - server: "" - port: "" - prefix: "" - suffix: "" - baseDN: "" - bindDN: "" - bind_password: - search_attr: "" - search_filter: "" - scheme: "" - tls: false - -## PostgreSQL service configuration -service: - ## PosgresSQL service type - type: ClusterIP - # clusterIP: None - port: 5432 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. - ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart - annotations: {} - ## Set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - # loadBalancerIP: - - ## Load Balancer sources - ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service - ## - # loadBalancerSourceRanges: - # - 10.10.10.0/24 - -## Start master and slave(s) pod(s) without limitations on shm memory. -## By default docker and containerd (and possibly other container runtimes) -## limit `/dev/shm` to `64M` (see e.g. the -## [docker issue](https://github.com/docker-library/postgres/issues/416) and the -## [containerd issue](https://github.com/containerd/containerd/issues/3654), -## which could be not enough if PostgreSQL uses parallel workers heavily. -## -shmVolume: - ## Set `shmVolume.enabled` to `true` to mount a new tmpfs volume to remove - ## this limitation. - ## - enabled: true - ## Set to `true` to `chmod 777 /dev/shm` on a initContainer. - ## This option is ingored if `volumePermissions.enabled` is `false` - ## - chmod: - enabled: true - -## PostgreSQL data Persistent Volume Storage Class -## If defined, storageClassName: -## If set to "-", storageClassName: "", which disables dynamic provisioning -## If undefined (the default) or set to null, no storageClassName spec is -## set, choosing the default provisioner. (gp2 on AWS, standard on -## GKE, AWS & OpenStack) -## -persistence: - enabled: true - ## A manually managed Persistent Volume and Claim - ## If defined, PVC must be created manually before volume will be bound - ## The value is evaluated as a template, so, for example, the name can depend on .Release or .Chart - ## - # existingClaim: - - ## The path the volume will be mounted at, useful when using different - ## PostgreSQL images. - ## - mountPath: /bitnami/postgresql - - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - ## - subPath: "" - - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - annotations: {} - -## updateStrategy for PostgreSQL StatefulSet and its slaves StatefulSets -## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies -updateStrategy: - type: RollingUpdate - -## -## PostgreSQL Master parameters -## -master: - ## Node, affinity, tolerations, and priorityclass settings for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption - nodeSelector: {} - affinity: {} - tolerations: [] - labels: {} - annotations: {} - podLabels: {} - podAnnotations: {} - priorityClassName: "" - extraInitContainers: | - # - name: do-something - # image: busybox - # command: ['do', 'something'] - - ## Additional PostgreSQL Master Volume mounts - ## - extraVolumeMounts: [] - ## Additional PostgreSQL Master Volumes - ## - extraVolumes: [] - ## Add sidecars to the pod - ## - ## For example: - ## sidecars: - ## - name: your-image-name - ## image: your-image - ## imagePullPolicy: Always - ## ports: - ## - name: portname - ## containerPort: 1234 - sidecars: [] - -## -## PostgreSQL Slave parameters -## -slave: - ## Node, affinity, tolerations, and priorityclass settings for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption - nodeSelector: {} - affinity: {} - tolerations: [] - labels: {} - annotations: {} - podLabels: {} - podAnnotations: {} - priorityClassName: "" - extraInitContainers: | - # - name: do-something - # image: busybox - # command: ['do', 'something'] - ## Additional PostgreSQL Slave Volume mounts - ## - extraVolumeMounts: [] - ## Additional PostgreSQL Slave Volumes - ## - extraVolumes: [] - ## Add sidecars to the pod - ## - ## For example: - ## sidecars: - ## - name: your-image-name - ## image: your-image - ## imagePullPolicy: Always - ## ports: - ## - name: portname - ## containerPort: 1234 - sidecars: [] - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -## -resources: - requests: - memory: 256Mi - cpu: 250m - -networkPolicy: - ## Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. - ## - enabled: false - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port PostgreSQL is listening - ## on. When true, PostgreSQL will accept connections from any source - ## (with the correct destination port). - ## - allowExternal: true - - ## 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 DB. - ## But sometimes, we want the DB 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. - ## - # explicitNamespacesSelector: - # matchLabels: - # role: frontend - # matchExpressions: - # - {key: role, operator: In, values: [frontend]} - -## Configure extra options for liveness and readiness probes -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) -livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - -readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - -## Configure metrics exporter -## -metrics: - enabled: false - # resources: {} - service: - type: ClusterIP - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "9187" - loadBalancerIP: - serviceMonitor: - enabled: false - additionalLabels: {} - # namespace: monitoring - # interval: 30s - # scrapeTimeout: 10s - ## Custom PrometheusRule to be defined - ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart - ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions - prometheusRule: - enabled: false - additionalLabels: {} - namespace: "" - rules: [] - ## These are just examples rules, please adapt them to your needs. - ## Make sure to constraint the rules to the current postgresql service. - # - alert: HugeReplicationLag - # expr: pg_replication_lag{service="{{ template "postgresql.fullname" . }}-metrics"} / 3600 > 1 - # for: 1m - # labels: - # severity: critical - # annotations: - # description: replication for {{ template "postgresql.fullname" . }} PostgreSQL is lagging by {{ "{{ $value }}" }} hour(s). - # summary: PostgreSQL replication is lagging by {{ "{{ $value }}" }} hour(s). - image: - registry: docker.io - repository: bitnami/postgres-exporter - tag: 0.8.0-debian-10-r28 - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - ## Define additional custom metrics - ## ref: https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file - # customMetrics: - # pg_database: - # query: "SELECT d.datname AS name, CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT') THEN pg_catalog.pg_database_size(d.datname) ELSE 0 END AS size FROM pg_catalog.pg_database d where datname not in ('template0', 'template1', 'postgres')" - # metrics: - # - name: - # usage: "LABEL" - # description: "Name of the database" - # - size_bytes: - # usage: "GAUGE" - # description: "Size of the database in bytes" - ## Pod Security Context - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - ## - securityContext: - enabled: false - runAsUser: 1001 - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## Configure extra options for liveness and readiness probes - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 diff --git a/infra/charts/feast/charts/prometheus-11.0.2.tgz b/infra/charts/feast/charts/prometheus-11.0.2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..32b3abbe4e59c96e000bbbe748d0744d1cff97f8 GIT binary patch literal 32813 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.8.0" diff --git a/infra/charts/feast/charts/prometheus/README.md b/infra/charts/feast/charts/prometheus/README.md deleted file mode 100644 index dc32dcd15a8..00000000000 --- a/infra/charts/feast/charts/prometheus/README.md +++ /dev/null @@ -1,471 +0,0 @@ -# Prometheus - -[Prometheus](https://prometheus.io/), a [Cloud Native Computing Foundation](https://cncf.io/) project, is a systems and service monitoring system. It collects metrics from configured targets at given intervals, evaluates rule expressions, displays the results, and can trigger alerts if some condition is observed to be true. - -## TL;DR; - -```console -$ helm install stable/prometheus -``` - -## Introduction - -This chart bootstraps a [Prometheus](https://prometheus.io/) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -## Prerequisites - -- Kubernetes 1.3+ with Beta APIs enabled - -## Installing the Chart - -To install the chart with the release name `my-release`: - -```console -$ helm install --name my-release stable/prometheus -``` - -The command deploys Prometheus on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. - -> **Tip**: List all releases using `helm list` - -## Uninstalling the Chart - -To uninstall/delete the `my-release` deployment: - -```console -$ helm delete my-release -``` - -The command removes all the Kubernetes components associated with the chart and deletes the release. - -## Prometheus 2.x - -Prometheus version 2.x has made changes to alertmanager, storage and recording rules. Check out the migration guide [here](https://prometheus.io/docs/prometheus/2.0/migration/) - -Users of this chart will need to update their alerting rules to the new format before they can upgrade. - -## Upgrading from previous chart versions. - -Version 9.0 adds a new option to enable or disable the Prometheus Server. -This supports the use case of running a Prometheus server in one k8s cluster and scraping exporters in another cluster while using the same chart for each deployment. -To install the server `server.enabled` must be set to `true`. - -As of version 5.0, this chart uses Prometheus 2.x. This version of prometheus introduces a new data format and is not compatible with prometheus 1.x. It is recommended to install this as a new release, as updating existing releases will not work. See the [prometheus docs](https://prometheus.io/docs/prometheus/latest/migration/#storage) for instructions on retaining your old data. - -### Example migration - -Assuming you have an existing release of the prometheus chart, named `prometheus-old`. In order to update to prometheus 2.x while keeping your old data do the following: - -1. Update the `prometheus-old` release. Disable scraping on every component besides the prometheus server, similar to the configuration below: - - ``` - alertmanager: - enabled: false - alertmanagerFiles: - alertmanager.yml: "" - kubeStateMetrics: - enabled: false - nodeExporter: - enabled: false - pushgateway: - enabled: false - server: - extraArgs: - storage.local.retention: 720h - serverFiles: - alerts: "" - prometheus.yml: "" - rules: "" - ``` - -1. Deploy a new release of the chart with version 5.0+ using prometheus 2.x. In the values.yaml set the scrape config as usual, and also add the `prometheus-old` instance as a remote-read target. - - ``` - prometheus.yml: - ... - remote_read: - - url: http://prometheus-old/api/v1/read - ... - ``` - - Old data will be available when you query the new prometheus instance. - -## Scraping Pod Metrics via Annotations - -This chart uses a default configuration that causes prometheus -to scrape a variety of kubernetes resource types, provided they have the correct annotations. -In this section we describe how to configure pods to be scraped; -for information on how other resource types can be scraped you can -do a `helm template` to get the kubernetes resource definitions, -and then reference the prometheus configuration in the ConfigMap against the prometheus documentation -for [relabel_config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) -and [kubernetes_sd_config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config). - -In order to get prometheus to scrape pods, you must add annotations to the the pods as below: - -``` -metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/path: /metrics - prometheus.io/port: "8080" -spec: -... -``` - -You should adjust `prometheus.io/path` based on the URL that your pod serves metrics from. -`prometheus.io/port` should be set to the port that your pod serves metrics from. -Note that the values for `prometheus.io/scrape` and `prometheus.io/port` must be -enclosed in double quotes. - -## Configuration - -The following table lists the configurable parameters of the Prometheus chart and their default values. - -Parameter | Description | Default ---------- | ----------- | ------- -`alertmanager.enabled` | If true, create alertmanager | `true` -`alertmanager.name` | alertmanager container name | `alertmanager` -`alertmanager.image.repository` | alertmanager container image repository | `prom/alertmanager` -`alertmanager.image.tag` | alertmanager container image tag | `v0.20.0` -`alertmanager.image.pullPolicy` | alertmanager container image pull policy | `IfNotPresent` -`alertmanager.prefixURL` | The prefix slug at which the server can be accessed | `` -`alertmanager.baseURL` | The external url at which the server can be accessed | `"http://localhost:9093"` -`alertmanager.extraArgs` | Additional alertmanager container arguments | `{}` -`alertmanager.extraSecretMounts` | Additional alertmanager Secret mounts | `[]` -`alertmanager.configMapOverrideName` | Prometheus alertmanager ConfigMap override where full-name is `{{.Release.Name}}-{{.Values.alertmanager.configMapOverrideName}}` and setting this value will prevent the default alertmanager ConfigMap from being generated | `""` -`alertmanager.configFromSecret` | The name of a secret in the same kubernetes namespace which contains the Alertmanager config, setting this value will prevent the default alertmanager ConfigMap from being generated | `""` -`alertmanager.configFileName` | The configuration file name to be loaded to alertmanager. Must match the key within configuration loaded from ConfigMap/Secret. | `alertmanager.yml` -`alertmanager.ingress.enabled` | If true, alertmanager Ingress will be created | `false` -`alertmanager.ingress.annotations` | alertmanager Ingress annotations | `{}` -`alertmanager.ingress.extraLabels` | alertmanager Ingress additional labels | `{}` -`alertmanager.ingress.hosts` | alertmanager Ingress hostnames | `[]` -`alertmanager.ingress.extraPaths` | Ingress extra paths to prepend to every alertmanager host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions) | `[]` -`alertmanager.ingress.tls` | alertmanager Ingress TLS configuration (YAML) | `[]` -`alertmanager.nodeSelector` | node labels for alertmanager pod assignment | `{}` -`alertmanager.tolerations` | node taints to tolerate (requires Kubernetes >=1.6) | `[]` -`alertmanager.affinity` | pod affinity | `{}` -`alertmanager.podDisruptionBudget.enabled` | If true, create a PodDisruptionBudget | `false` -`alertmanager.podDisruptionBudget.maxUnavailable` | Maximum unavailable instances in PDB | `1` -`alertmanager.schedulerName` | alertmanager alternate scheduler name | `nil` -`alertmanager.persistentVolume.enabled` | If true, alertmanager will create a Persistent Volume Claim | `true` -`alertmanager.persistentVolume.accessModes` | alertmanager data Persistent Volume access modes | `[ReadWriteOnce]` -`alertmanager.persistentVolume.annotations` | Annotations for alertmanager Persistent Volume Claim | `{}` -`alertmanager.persistentVolume.existingClaim` | alertmanager data Persistent Volume existing claim name | `""` -`alertmanager.persistentVolume.mountPath` | alertmanager data Persistent Volume mount root path | `/data` -`alertmanager.persistentVolume.size` | alertmanager data Persistent Volume size | `2Gi` -`alertmanager.persistentVolume.storageClass` | alertmanager data Persistent Volume Storage Class | `unset` -`alertmanager.persistentVolume.volumeBindingMode` | alertmanager data Persistent Volume Binding Mode | `unset` -`alertmanager.persistentVolume.subPath` | Subdirectory of alertmanager data Persistent Volume to mount | `""` -`alertmanager.podAnnotations` | annotations to be added to alertmanager pods | `{}` -`alertmanager.podLabels` | labels to be added to Prometheus AlertManager pods | `{}` -`alertmanager.podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | -`alertmanager.replicaCount` | desired number of alertmanager pods | `1` -`alertmanager.statefulSet.enabled` | If true, use a statefulset instead of a deployment for pod management | `false` -`alertmanager.statefulSet.podManagementPolicy` | podManagementPolicy of alertmanager pods | `OrderedReady` -`alertmanager.statefulSet.headless.annotations` | annotations for alertmanager headless service | `{}` -`alertmanager.statefulSet.headless.labels` | labels for alertmanager headless service | `{}` -`alertmanager.statefulSet.headless.enableMeshPeer` | If true, enable the mesh peer endpoint for the headless service | `{}` -`alertmanager.statefulSet.headless.servicePort` | alertmanager headless service port | `80` -`alertmanager.priorityClassName` | alertmanager priorityClassName | `nil` -`alertmanager.resources` | alertmanager pod resource requests & limits | `{}` -`alertmanager.securityContext` | Custom [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for Alert Manager containers | `{}` -`alertmanager.service.annotations` | annotations for alertmanager service | `{}` -`alertmanager.service.clusterIP` | internal alertmanager cluster service IP | `""` -`alertmanager.service.externalIPs` | alertmanager service external IP addresses | `[]` -`alertmanager.service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` -`alertmanager.service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to load balancer (if supported) | `[]` -`alertmanager.service.servicePort` | alertmanager service port | `80` -`alertmanager.service.sessionAffinity` | Session Affinity for alertmanager service, can be `None` or `ClientIP` | `None` -`alertmanager.service.type` | type of alertmanager service to create | `ClusterIP` -`alertmanager.strategy` | Deployment strategy | `{ "type": "RollingUpdate" }` -`alertmanagerFiles.alertmanager.yml` | Prometheus alertmanager configuration | example configuration -`configmapReload.prometheus.enabled` | If false, the configmap-reload container for Prometheus will not be deployed | `true` -`configmapReload.prometheus.name` | configmap-reload container name | `configmap-reload` -`configmapReload.prometheus.image.repository` | configmap-reload container image repository | `jimmidyson/configmap-reload` -`configmapReload.prometheus.image.tag` | configmap-reload container image tag | `v0.3.0` -`configmapReload.prometheus.image.pullPolicy` | configmap-reload container image pull policy | `IfNotPresent` -`configmapReload.prometheus.extraArgs` | Additional configmap-reload container arguments | `{}` -`configmapReload.prometheus.extraVolumeDirs` | Additional configmap-reload volume directories | `{}` -`configmapReload.prometheus.extraConfigmapMounts` | Additional configmap-reload configMap mounts | `[]` -`configmapReload.prometheus.resources` | configmap-reload pod resource requests & limits | `{}` -`configmapReload.alertmanager.enabled` | If false, the configmap-reload container for AlertManager will not be deployed | `true` -`configmapReload.alertmanager.name` | configmap-reload container name | `configmap-reload` -`configmapReload.alertmanager.image.repository` | configmap-reload container image repository | `jimmidyson/configmap-reload` -`configmapReload.alertmanager.image.tag` | configmap-reload container image tag | `v0.3.0` -`configmapReload.alertmanager.image.pullPolicy` | configmap-reload container image pull policy | `IfNotPresent` -`configmapReload.alertmanager.extraArgs` | Additional configmap-reload container arguments | `{}` -`configmapReload.alertmanager.extraVolumeDirs` | Additional configmap-reload volume directories | `{}` -`configmapReload.alertmanager.extraConfigmapMounts` | Additional configmap-reload configMap mounts | `[]` -`configmapReload.alertmanager.resources` | configmap-reload pod resource requests & limits | `{}` -`initChownData.enabled` | If false, don't reset data ownership at startup | true -`initChownData.name` | init-chown-data container name | `init-chown-data` -`initChownData.image.repository` | init-chown-data container image repository | `busybox` -`initChownData.image.tag` | init-chown-data container image tag | `latest` -`initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` -`initChownData.resources` | init-chown-data pod resource requests & limits | `{}` -`kubeStateMetrics.enabled` | If true, create kube-state-metrics sub-chart, see the [kube-state-metrics chart for configuration options](https://github.com/helm/charts/tree/master/stable/kube-state-metrics) | `true` -`nodeExporter.enabled` | If true, create node-exporter | `true` -`nodeExporter.name` | node-exporter container name | `node-exporter` -`nodeExporter.image.repository` | node-exporter container image repository| `prom/node-exporter` -`nodeExporter.image.tag` | node-exporter container image tag | `v0.18.1` -`nodeExporter.image.pullPolicy` | node-exporter container image pull policy | `IfNotPresent` -`nodeExporter.extraArgs` | Additional node-exporter container arguments | `{}` -`nodeExporter.extraHostPathMounts` | Additional node-exporter hostPath mounts | `[]` -`nodeExporter.extraConfigmapMounts` | Additional node-exporter configMap mounts | `[]` -`nodeExporter.hostNetwork` | If true, node-exporter pods share the host network namespace | `true` -`nodeExporter.hostPID` | If true, node-exporter pods share the host PID namespace | `true` -`nodeExporter.nodeSelector` | node labels for node-exporter pod assignment | `{}` -`nodeExporter.podAnnotations` | annotations to be added to node-exporter pods | `{}` -`nodeExporter.pod.labels` | labels to be added to node-exporter pods | `{}` -`nodeExporter.podDisruptionBudget.enabled` | If true, create a PodDisruptionBudget | `false` -`nodeExporter.podDisruptionBudget.maxUnavailable` | Maximum unavailable instances in PDB | `1` -`nodeExporter.podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | -`nodeExporter.podSecurityPolicy.enabled` | Specify if a Pod Security Policy for node-exporter must be created | `false` -`nodeExporter.tolerations` | node taints to tolerate (requires Kubernetes >=1.6) | `[]` -`nodeExporter.priorityClassName` | node-exporter priorityClassName | `nil` -`nodeExporter.resources` | node-exporter resource requests and limits (YAML) | `{}` -`nodeExporter.securityContext` | securityContext for containers in pod | `{}` -`nodeExporter.service.annotations` | annotations for node-exporter service | `{prometheus.io/scrape: "true"}` -`nodeExporter.service.clusterIP` | internal node-exporter cluster service IP | `None` -`nodeExporter.service.externalIPs` | node-exporter service external IP addresses | `[]` -`nodeExporter.service.hostPort` | node-exporter service host port | `9100` -`nodeExporter.service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` -`nodeExporter.service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to load balancer (if supported) | `[]` -`nodeExporter.service.servicePort` | node-exporter service port | `9100` -`nodeExporter.service.type` | type of node-exporter service to create | `ClusterIP` -`podSecurityPolicy.enabled` | If true, create & use pod security policies resources | `false` -`pushgateway.enabled` | If true, create pushgateway | `true` -`pushgateway.name` | pushgateway container name | `pushgateway` -`pushgateway.image.repository` | pushgateway container image repository | `prom/pushgateway` -`pushgateway.image.tag` | pushgateway container image tag | `v1.0.1` -`pushgateway.image.pullPolicy` | pushgateway container image pull policy | `IfNotPresent` -`pushgateway.extraArgs` | Additional pushgateway container arguments | `{}` -`pushgateway.ingress.enabled` | If true, pushgateway Ingress will be created | `false` -`pushgateway.ingress.annotations` | pushgateway Ingress annotations | `{}` -`pushgateway.ingress.hosts` | pushgateway Ingress hostnames | `[]` -`pushgateway.ingress.extraPaths` | Ingress extra paths to prepend to every pushgateway host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions) | `[]` -`pushgateway.ingress.tls` | pushgateway Ingress TLS configuration (YAML) | `[]` -`pushgateway.nodeSelector` | node labels for pushgateway pod assignment | `{}` -`pushgateway.podAnnotations` | annotations to be added to pushgateway pods | `{}` -`pushgateway.podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | -`pushgateway.tolerations` | node taints to tolerate (requires Kubernetes >=1.6) | `[]` -`pushgateway.replicaCount` | desired number of pushgateway pods | `1` -`pushgateway.podDisruptionBudget.enabled` | If true, create a PodDisruptionBudget | `false` -`pushgateway.podDisruptionBudget.maxUnavailable` | Maximum unavailable instances in PDB | `1` -`pushgateway.schedulerName` | pushgateway alternate scheduler name | `nil` -`pushgateway.persistentVolume.enabled` | If true, Prometheus pushgateway will create a Persistent Volume Claim | `false` -`pushgateway.persistentVolume.accessModes` | Prometheus pushgateway data Persistent Volume access modes | `[ReadWriteOnce]` -`pushgateway.persistentVolume.annotations` | Prometheus pushgateway data Persistent Volume annotations | `{}` -`pushgateway.persistentVolume.existingClaim` | Prometheus pushgateway data Persistent Volume existing claim name | `""` -`pushgateway.persistentVolume.mountPath` | Prometheus pushgateway data Persistent Volume mount root path | `/data` -`pushgateway.persistentVolume.size` | Prometheus pushgateway data Persistent Volume size | `2Gi` -`pushgateway.persistentVolume.storageClass` | Prometheus pushgateway data Persistent Volume Storage Class | `unset` -`pushgateway.persistentVolume.volumeBindingMode` | Prometheus pushgateway data Persistent Volume Binding Mode | `unset` -`pushgateway.persistentVolume.subPath` | Subdirectory of Prometheus server data Persistent Volume to mount | `""` -`pushgateway.priorityClassName` | pushgateway priorityClassName | `nil` -`pushgateway.resources` | pushgateway pod resource requests & limits | `{}` -`pushgateway.service.annotations` | annotations for pushgateway service | `{}` -`pushgateway.service.clusterIP` | internal pushgateway cluster service IP | `""` -`pushgateway.service.externalIPs` | pushgateway service external IP addresses | `[]` -`pushgateway.service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` -`pushgateway.service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to load balancer (if supported) | `[]` -`pushgateway.service.servicePort` | pushgateway service port | `9091` -`pushgateway.service.type` | type of pushgateway service to create | `ClusterIP` -`pushgateway.strategy` | Deployment strategy | `{ "type": "RollingUpdate" }` -`rbac.create` | If true, create & use RBAC resources | `true` -`server.enabled` | If false, Prometheus server will not be created | `true` -`server.name` | Prometheus server container name | `server` -`server.image.repository` | Prometheus server container image repository | `prom/prometheus` -`server.image.tag` | Prometheus server container image tag | `v2.16.0` -`server.image.pullPolicy` | Prometheus server container image pull policy | `IfNotPresent` -`server.configPath` | Path to a prometheus server config file on the container FS | `/etc/config/prometheus.yml` -`server.global.scrape_interval` | How frequently to scrape targets by default | `1m` -`server.global.scrape_timeout` | How long until a scrape request times out | `10s` -`server.global.evaluation_interval` | How frequently to evaluate rules | `1m` -`server.remoteWrite` | The remote write feature of Prometheus allow transparently sending samples. | `{}` -`server.remoteRead` | The remote read feature of Prometheus allow transparently receiving samples. | `{}` -`server.extraArgs` | Additional Prometheus server container arguments | `{}` -`server.extraFlags` | Additional Prometheus server container flags | `["web.enable-lifecycle"]` -`server.extraInitContainers` | Init containers to launch alongside the server | `[]` -`server.prefixURL` | The prefix slug at which the server can be accessed | `` -`server.baseURL` | The external url at which the server can be accessed | `` -`server.env` | Prometheus server environment variables | `[]` -`server.extraHostPathMounts` | Additional Prometheus server hostPath mounts | `[]` -`server.extraConfigmapMounts` | Additional Prometheus server configMap mounts | `[]` -`server.extraSecretMounts` | Additional Prometheus server Secret mounts | `[]` -`server.extraVolumeMounts` | Additional Prometheus server Volume mounts | `[]` -`server.extraVolumes` | Additional Prometheus server Volumes | `[]` -`server.configMapOverrideName` | Prometheus server ConfigMap override where full-name is `{{.Release.Name}}-{{.Values.server.configMapOverrideName}}` and setting this value will prevent the default server ConfigMap from being generated | `""` -`server.ingress.enabled` | If true, Prometheus server Ingress will be created | `false` -`server.ingress.annotations` | Prometheus server Ingress annotations | `[]` -`server.ingress.extraLabels` | Prometheus server Ingress additional labels | `{}` -`server.ingress.hosts` | Prometheus server Ingress hostnames | `[]` -`server.ingress.extraPaths` | Ingress extra paths to prepend to every Prometheus server host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions) | `[]` -`server.ingress.tls` | Prometheus server Ingress TLS configuration (YAML) | `[]` -`server.nodeSelector` | node labels for Prometheus server pod assignment | `{}` -`server.tolerations` | node taints to tolerate (requires Kubernetes >=1.6) | `[]` -`server.affinity` | pod affinity | `{}` -`server.podDisruptionBudget.enabled` | If true, create a PodDisruptionBudget | `false` -`server.podDisruptionBudget.maxUnavailable` | Maximum unavailable instances in PDB | `1` -`server.priorityClassName` | Prometheus server priorityClassName | `nil` -`server.schedulerName` | Prometheus server alternate scheduler name | `nil` -`server.persistentVolume.enabled` | If true, Prometheus server will create a Persistent Volume Claim | `true` -`server.persistentVolume.accessModes` | Prometheus server data Persistent Volume access modes | `[ReadWriteOnce]` -`server.persistentVolume.annotations` | Prometheus server data Persistent Volume annotations | `{}` -`server.persistentVolume.existingClaim` | Prometheus server data Persistent Volume existing claim name | `""` -`server.persistentVolume.mountPath` | Prometheus server data Persistent Volume mount root path | `/data` -`server.persistentVolume.size` | Prometheus server data Persistent Volume size | `8Gi` -`server.persistentVolume.storageClass` | Prometheus server data Persistent Volume Storage Class | `unset` -`server.persistentVolume.volumeBindingMode` | Prometheus server data Persistent Volume Binding Mode | `unset` -`server.persistentVolume.subPath` | Subdirectory of Prometheus server data Persistent Volume to mount | `""` -`server.emptyDir.sizeLimit` | emptyDir sizeLimit if a Persistent Volume is not used | `""` -`server.podAnnotations` | annotations to be added to Prometheus server pods | `{}` -`server.podLabels` | labels to be added to Prometheus server pods | `{}` -`server.alertmanagers` | Prometheus AlertManager configuration for the Prometheus server | `{}` -`server.deploymentAnnotations` | annotations to be added to Prometheus server deployment | `{}` -`server.podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | -`server.replicaCount` | desired number of Prometheus server pods | `1` -`server.statefulSet.enabled` | If true, use a statefulset instead of a deployment for pod management | `false` -`server.statefulSet.annotations` | annotations to be added to Prometheus server stateful set | `{}` -`server.statefulSet.labels` | labels to be added to Prometheus server stateful set | `{}` -`server.statefulSet.podManagementPolicy` | podManagementPolicy of server pods | `OrderedReady` -`server.statefulSet.headless.annotations` | annotations for Prometheus server headless service | `{}` -`server.statefulSet.headless.labels` | labels for Prometheus server headless service | `{}` -`server.statefulSet.headless.servicePort` | Prometheus server headless service port | `80` -`server.resources` | Prometheus server resource requests and limits | `{}` -`server.verticalAutoscaler.enabled` | If true a VPA object will be created for the controller (either StatefulSet or Deployemnt, based on above configs) | `false` -`server.securityContext` | Custom [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for server containers | `{}` -`server.service.annotations` | annotations for Prometheus server service | `{}` -`server.service.clusterIP` | internal Prometheus server cluster service IP | `""` -`server.service.externalIPs` | Prometheus server service external IP addresses | `[]` -`server.service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` -`server.service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to load balancer (if supported) | `[]` -`server.service.nodePort` | Port to be used as the service NodePort (ignored if `server.service.type` is not `NodePort`) | `0` -`server.service.servicePort` | Prometheus server service port | `80` -`server.service.sessionAffinity` | Session Affinity for server service, can be `None` or `ClientIP` | `None` -`server.service.type` | type of Prometheus server service to create | `ClusterIP` -`server.service.gRPC.enabled` | If true, open a second port on the service for gRPC | `false` -`server.service.gRPC.servicePort` | Prometheus service gRPC port, (ignored if `server.service.gRPC.enabled` is not `true`) | `10901` -`server.service.gRPC.nodePort` | Port to be used as gRPC nodePort in the prometheus service | `0` -`server.service.statefulsetReplica.enabled` | If true, send the traffic from the service to only one replica of the replicaset | `false` -`server.service.statefulsetReplica.replica` | Which replica to send the traffice to | `0` -`server.sidecarContainers` | array of snippets with your sidecar containers for prometheus server | `""` -`server.strategy` | Deployment strategy | `{ "type": "RollingUpdate" }` -`serviceAccounts.alertmanager.create` | If true, create the alertmanager service account | `true` -`serviceAccounts.alertmanager.name` | name of the alertmanager service account to use or create | `{{ prometheus.alertmanager.fullname }}` -`serviceAccounts.kubeStateMetrics.create` | If true, create the kubeStateMetrics service account | `true` -`serviceAccounts.kubeStateMetrics.name` | name of the kubeStateMetrics service account to use or create | `{{ prometheus.kubeStateMetrics.fullname }}` -`serviceAccounts.nodeExporter.create` | If true, create the nodeExporter service account | `true` -`serviceAccounts.nodeExporter.name` | name of the nodeExporter service account to use or create | `{{ prometheus.nodeExporter.fullname }}` -`serviceAccounts.pushgateway.create` | If true, create the pushgateway service account | `true` -`serviceAccounts.pushgateway.name` | name of the pushgateway service account to use or create | `{{ prometheus.pushgateway.fullname }}` -`serviceAccounts.server.create` | If true, create the server service account | `true` -`serviceAccounts.server.name` | name of the server service account to use or create | `{{ prometheus.server.fullname }}` -`server.terminationGracePeriodSeconds` | Prometheus server Pod termination grace period | `300` -`server.retention` | (optional) Prometheus data retention | `"15d"` -`serverFiles.alerts` | (Deprecated) Prometheus server alerts configuration | `{}` -`serverFiles.rules` | (Deprecated) Prometheus server rules configuration | `{}` -`serverFiles.alerting_rules.yml` | Prometheus server alerts configuration | `{}` -`serverFiles.recording_rules.yml` | Prometheus server rules configuration | `{}` -`serverFiles.prometheus.yml` | Prometheus server scrape configuration | example configuration -`extraScrapeConfigs` | Prometheus server additional scrape configuration | "" -`alertRelabelConfigs` | Prometheus server [alert relabeling configs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs) for H/A prometheus | "" -`networkPolicy.enabled` | Enable NetworkPolicy | `false` | - -Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, - -```console -$ helm install stable/prometheus --name my-release \ - --set server.terminationGracePeriodSeconds=360 -``` - -Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, - -```console -$ helm install stable/prometheus --name my-release -f values.yaml -``` - -> **Tip**: You can use the default [values.yaml](values.yaml) - -Note that you have multiple yaml files. This is particularly useful when you have alerts belonging to multiple services in the cluster. For example, - -```yaml -# values.yaml -# ... - -# service1-alert.yaml -serverFiles: - alerts: - service1: - - alert: anAlert - # ... - -# service2-alert.yaml -serverFiles: - alerts: - service2: - - alert: anAlert - # ... -``` - -```console -$ helm install stable/prometheus --name my-release -f values.yaml -f service1-alert.yaml -f service2-alert.yaml -``` - -### RBAC Configuration -Roles and RoleBindings resources will be created automatically for `server` and `kubeStateMetrics` services. - -To manually setup RBAC you need to set the parameter `rbac.create=false` and specify the service account to be used for each service by setting the parameters: `serviceAccounts.{{ component }}.create` to `false` and `serviceAccounts.{{ component }}.name` to the name of a pre-existing service account. - -> **Tip**: You can refer to the default `*-clusterrole.yaml` and `*-clusterrolebinding.yaml` files in [templates](templates/) to customize your own. - -### ConfigMap Files -AlertManager is configured through [alertmanager.yml](https://prometheus.io/docs/alerting/configuration/). This file (and any others listed in `alertmanagerFiles`) will be mounted into the `alertmanager` pod. - -Prometheus is configured through [prometheus.yml](https://prometheus.io/docs/operating/configuration/). This file (and any others listed in `serverFiles`) will be mounted into the `server` pod. - -### Ingress TLS -If your cluster allows automatic creation/retrieval of TLS certificates (e.g. [kube-lego](https://github.com/jetstack/kube-lego)), please refer to the documentation for that mechanism. - -To manually configure TLS, first create/retrieve a key & certificate pair for the address(es) you wish to protect. Then create a TLS secret in the namespace: - -```console -kubectl create secret tls prometheus-server-tls --cert=path/to/tls.cert --key=path/to/tls.key -``` - -Include the secret's name, along with the desired hostnames, in the alertmanager/server Ingress TLS section of your custom `values.yaml` file: - -```yaml -server: - ingress: - ## If true, Prometheus server Ingress will be created - ## - enabled: true - - ## Prometheus server Ingress hostnames - ## Must be provided if Ingress is enabled - ## - hosts: - - prometheus.domain.com - - ## Prometheus server Ingress TLS configuration - ## Secrets must be manually created in the namespace - ## - tls: - - secretName: prometheus-server-tls - hosts: - - prometheus.domain.com -``` - -### NetworkPolicy - -Enabling Network Policy for Prometheus will secure connections to Alert Manager -and Kube State Metrics by only accepting connections from Prometheus Server. -All inbound connections to Prometheus Server are still allowed. - -To enable network policy for Prometheus, install a networking plugin that -implements the Kubernetes NetworkPolicy spec, and set `networkPolicy.enabled` to true. - -If NetworkPolicy is enabled for Prometheus' scrape targets, you may also need -to manually create a networkpolicy which allows it. diff --git a/infra/charts/feast/charts/prometheus/requirements.yaml b/infra/charts/feast/charts/prometheus/requirements.yaml deleted file mode 100644 index 6e079ae7d81..00000000000 --- a/infra/charts/feast/charts/prometheus/requirements.yaml +++ /dev/null @@ -1,7 +0,0 @@ -dependencies: - - - name: kube-state-metrics - version: "2.7.*" - repository: https://kubernetes-charts.storage.googleapis.com/ - condition: kubeStateMetrics.enabled - diff --git a/infra/charts/feast/charts/prometheus/templates/NOTES.txt b/infra/charts/feast/charts/prometheus/templates/NOTES.txt deleted file mode 100644 index 0e8868f0b72..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/NOTES.txt +++ /dev/null @@ -1,112 +0,0 @@ -{{- if .Values.server.enabled -}} -The Prometheus server can be accessed via port {{ .Values.server.service.servicePort }} on the following DNS name from within your cluster: -{{ template "prometheus.server.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - -{{ if .Values.server.ingress.enabled -}} -From outside the cluster, the server URL(s) are: -{{- range .Values.server.ingress.hosts }} -http://{{ . }} -{{- end }} -{{- else }} -Get the Prometheus server URL by running these commands in the same shell: -{{- if contains "NodePort" .Values.server.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.server.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.server.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 {{ .Release.Namespace }} -w {{ template "prometheus.server.fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.server.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo http://$SERVICE_IP:{{ .Values.server.service.servicePort }} -{{- else if contains "ClusterIP" .Values.server.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.server.name }}" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9090 -{{- end }} -{{- end }} - -{{- if .Values.server.persistentVolume.enabled }} -{{- else }} -################################################################################# -###### WARNING: Persistence is disabled!!! You will lose your data when ##### -###### the Server pod is terminated. ##### -################################################################################# -{{- end }} -{{- end }} - -{{ if .Values.alertmanager.enabled }} -The Prometheus alertmanager can be accessed via port {{ .Values.alertmanager.service.servicePort }} on the following DNS name from within your cluster: -{{ template "prometheus.alertmanager.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - -{{ if .Values.alertmanager.ingress.enabled -}} -From outside the cluster, the alertmanager URL(s) are: -{{- range .Values.alertmanager.ingress.hosts }} -http://{{ . }} -{{- end }} -{{- else }} -Get the Alertmanager URL by running these commands in the same shell: -{{- if contains "NodePort" .Values.alertmanager.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.alertmanager.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.alertmanager.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 {{ .Release.Namespace }} -w {{ template "prometheus.alertmanager.fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.alertmanager.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo http://$SERVICE_IP:{{ .Values.alertmanager.service.servicePort }} -{{- else if contains "ClusterIP" .Values.alertmanager.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.alertmanager.name }}" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9093 -{{- end }} -{{- end }} - -{{- if .Values.alertmanager.persistentVolume.enabled }} -{{- else }} -################################################################################# -###### WARNING: Persistence is disabled!!! You will lose your data when ##### -###### the AlertManager pod is terminated. ##### -################################################################################# -{{- end }} -{{- end }} - -{{- if .Values.nodeExporter.podSecurityPolicy.enabled }} -{{- else }} -################################################################################# -###### WARNING: Pod Security Policy has been moved to a global property. ##### -###### use .Values.podSecurityPolicy.enabled with pod-based ##### -###### annotations ##### -###### (e.g. .Values.nodeExporter.podSecurityPolicy.annotations) ##### -################################################################################# -{{- end }} - -{{ if .Values.pushgateway.enabled }} -The Prometheus PushGateway can be accessed via port {{ .Values.pushgateway.service.servicePort }} on the following DNS name from within your cluster: -{{ template "prometheus.pushgateway.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - -{{ if .Values.pushgateway.ingress.enabled -}} -From outside the cluster, the pushgateway URL(s) are: -{{- range .Values.pushgateway.ingress.hosts }} -http://{{ . }} -{{- end }} -{{- else }} -Get the PushGateway URL by running these commands in the same shell: -{{- if contains "NodePort" .Values.pushgateway.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.pushgateway.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.pushgateway.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 {{ .Release.Namespace }} -w {{ template "prometheus.pushgateway.fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.pushgateway.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo http://$SERVICE_IP:{{ .Values.pushgateway.service.servicePort }} -{{- else if contains "ClusterIP" .Values.pushgateway.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.pushgateway.name }}" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9091 -{{- end }} -{{- end }} -{{- end }} - -For more information on running Prometheus, visit: -https://prometheus.io/ diff --git a/infra/charts/feast/charts/prometheus/templates/_helpers.tpl b/infra/charts/feast/charts/prometheus/templates/_helpers.tpl deleted file mode 100644 index 295aa01c509..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/_helpers.tpl +++ /dev/null @@ -1,276 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "prometheus.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "prometheus.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create unified labels for prometheus components -*/}} -{{- define "prometheus.common.matchLabels" -}} -app: {{ template "prometheus.name" . }} -release: {{ .Release.Name }} -{{- end -}} - -{{- define "prometheus.common.metaLabels" -}} -chart: {{ template "prometheus.chart" . }} -heritage: {{ .Release.Service }} -{{- end -}} - -{{- define "prometheus.alertmanager.labels" -}} -{{ include "prometheus.alertmanager.matchLabels" . }} -{{ include "prometheus.common.metaLabels" . }} -{{- end -}} - -{{- define "prometheus.alertmanager.matchLabels" -}} -component: {{ .Values.alertmanager.name | quote }} -{{ include "prometheus.common.matchLabels" . }} -{{- end -}} - -{{- define "prometheus.kubeStateMetrics.labels" -}} -{{ include "prometheus.kubeStateMetrics.matchLabels" . }} -{{ include "prometheus.common.metaLabels" . }} -{{- end -}} - -{{- define "prometheus.kubeStateMetrics.matchLabels" -}} -component: {{ .Values.kubeStateMetrics.name | quote }} -{{ include "prometheus.common.matchLabels" . }} -{{- end -}} - -{{- define "prometheus.nodeExporter.labels" -}} -{{ include "prometheus.nodeExporter.matchLabels" . }} -{{ include "prometheus.common.metaLabels" . }} -{{- end -}} - -{{- define "prometheus.nodeExporter.matchLabels" -}} -component: {{ .Values.nodeExporter.name | quote }} -{{ include "prometheus.common.matchLabels" . }} -{{- end -}} - -{{- define "prometheus.pushgateway.labels" -}} -{{ include "prometheus.pushgateway.matchLabels" . }} -{{ include "prometheus.common.metaLabels" . }} -{{- end -}} - -{{- define "prometheus.pushgateway.matchLabels" -}} -component: {{ .Values.pushgateway.name | quote }} -{{ include "prometheus.common.matchLabels" . }} -{{- end -}} - -{{- define "prometheus.server.labels" -}} -{{ include "prometheus.server.matchLabels" . }} -{{ include "prometheus.common.metaLabels" . }} -{{- end -}} - -{{- define "prometheus.server.matchLabels" -}} -component: {{ .Values.server.name | quote }} -{{ include "prometheus.common.matchLabels" . }} -{{- 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). -*/}} -{{- define "prometheus.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create a fully qualified alertmanager name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} - -{{- define "prometheus.alertmanager.fullname" -}} -{{- if .Values.alertmanager.fullnameOverride -}} -{{- .Values.alertmanager.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- printf "%s-%s" .Release.Name .Values.alertmanager.name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s-%s" .Release.Name $name .Values.alertmanager.name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create a fully qualified kube-state-metrics name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "prometheus.kubeStateMetrics.fullname" -}} -{{- if .Values.kubeStateMetrics.fullnameOverride -}} -{{- .Values.kubeStateMetrics.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- printf "%s-%s" .Release.Name .Values.kubeStateMetrics.name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s-%s" .Release.Name $name .Values.kubeStateMetrics.name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create a fully qualified node-exporter name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "prometheus.nodeExporter.fullname" -}} -{{- if .Values.nodeExporter.fullnameOverride -}} -{{- .Values.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- printf "%s-%s" .Release.Name .Values.nodeExporter.name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s-%s" .Release.Name $name .Values.nodeExporter.name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create a fully qualified Prometheus server name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "prometheus.server.fullname" -}} -{{- if .Values.server.fullnameOverride -}} -{{- .Values.server.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- printf "%s-%s" .Release.Name .Values.server.name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s-%s" .Release.Name $name .Values.server.name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create a fully qualified pushgateway name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "prometheus.pushgateway.fullname" -}} -{{- if .Values.pushgateway.fullnameOverride -}} -{{- .Values.pushgateway.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- printf "%s-%s" .Release.Name .Values.pushgateway.name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s-%s" .Release.Name $name .Values.pushgateway.name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Return the appropriate apiVersion for deployment. -*/}} -{{- define "prometheus.deployment.apiVersion" -}} -{{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "extensions/v1beta1" -}} -{{- else if semverCompare "^1.9-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "apps/v1" -}} -{{- end -}} -{{- end -}} -{{/* -Return the appropriate apiVersion for daemonset. -*/}} -{{- define "prometheus.daemonset.apiVersion" -}} -{{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "extensions/v1beta1" -}} -{{- else if semverCompare "^1.9-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "apps/v1" -}} -{{- end -}} -{{- end -}} -{{/* -Return the appropriate apiVersion for networkpolicy. -*/}} -{{- define "prometheus.networkPolicy.apiVersion" -}} -{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "extensions/v1beta1" -}} -{{- else if semverCompare "^1.7-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "networking.k8s.io/v1" -}} -{{- end -}} -{{- end -}} -{{/* -Return the appropriate apiVersion for podsecuritypolicy. -*/}} -{{- define "prometheus.podSecurityPolicy.apiVersion" -}} -{{- if semverCompare ">=1.3-0, <1.10-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "extensions/v1beta1" -}} -{{- else if semverCompare "^1.10-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "policy/v1beta1" -}} -{{- end -}} -{{- end -}} - -{{/* -Create the name of the service account to use for the alertmanager component -*/}} -{{- define "prometheus.serviceAccountName.alertmanager" -}} -{{- if .Values.serviceAccounts.alertmanager.create -}} - {{ default (include "prometheus.alertmanager.fullname" .) .Values.serviceAccounts.alertmanager.name }} -{{- else -}} - {{ default "default" .Values.serviceAccounts.alertmanager.name }} -{{- end -}} -{{- end -}} - -{{/* -Create the name of the service account to use for the kubeStateMetrics component -*/}} -{{- define "prometheus.serviceAccountName.kubeStateMetrics" -}} -{{- if .Values.serviceAccounts.kubeStateMetrics.create -}} - {{ default (include "prometheus.kubeStateMetrics.fullname" .) .Values.serviceAccounts.kubeStateMetrics.name }} -{{- else -}} - {{ default "default" .Values.serviceAccounts.kubeStateMetrics.name }} -{{- end -}} -{{- end -}} - -{{/* -Create the name of the service account to use for the nodeExporter component -*/}} -{{- define "prometheus.serviceAccountName.nodeExporter" -}} -{{- if .Values.serviceAccounts.nodeExporter.create -}} - {{ default (include "prometheus.nodeExporter.fullname" .) .Values.serviceAccounts.nodeExporter.name }} -{{- else -}} - {{ default "default" .Values.serviceAccounts.nodeExporter.name }} -{{- end -}} -{{- end -}} - -{{/* -Create the name of the service account to use for the pushgateway component -*/}} -{{- define "prometheus.serviceAccountName.pushgateway" -}} -{{- if .Values.serviceAccounts.pushgateway.create -}} - {{ default (include "prometheus.pushgateway.fullname" .) .Values.serviceAccounts.pushgateway.name }} -{{- else -}} - {{ default "default" .Values.serviceAccounts.pushgateway.name }} -{{- end -}} -{{- end -}} - -{{/* -Create the name of the service account to use for the server component -*/}} -{{- define "prometheus.serviceAccountName.server" -}} -{{- if .Values.serviceAccounts.server.create -}} - {{ default (include "prometheus.server.fullname" .) .Values.serviceAccounts.server.name }} -{{- else -}} - {{ default "default" .Values.serviceAccounts.server.name }} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrole.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrole.yaml deleted file mode 100644 index 3cfc13300b2..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrole.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} - name: {{ template "prometheus.alertmanager.fullname" . }} -rules: -{{- if .Values.podSecurityPolicy.enabled }} - - apiGroups: - - extensions - resources: - - podsecuritypolicies - verbs: - - use - resourceNames: - - {{ template "prometheus.alertmanager.fullname" . }} -{{- else }} - [] -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrolebinding.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrolebinding.yaml deleted file mode 100644 index 925afcd3331..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-clusterrolebinding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} - name: {{ template "prometheus.alertmanager.fullname" . }} -subjects: - - kind: ServiceAccount - name: {{ template "prometheus.serviceAccountName.alertmanager" . }} - namespace: {{ .Release.Namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "prometheus.alertmanager.fullname" . }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-configmap.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-configmap.yaml deleted file mode 100644 index 6f6efcece92..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-configmap.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.alertmanager.enabled (and (empty .Values.alertmanager.configMapOverrideName) (empty .Values.alertmanager.configFromSecret)) -}} -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} - name: {{ template "prometheus.alertmanager.fullname" . }} -data: -{{- $root := . -}} -{{- range $key, $value := .Values.alertmanagerFiles }} - {{- if $key | regexMatch ".*\\.ya?ml$" }} - {{ $key }}: | -{{ toYaml $value | default "{}" | indent 4 }} - {{- else }} - {{ $key }}: {{ toYaml $value | indent 4 }} - {{- end }} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-deployment.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-deployment.yaml deleted file mode 100644 index 16ff6695043..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-deployment.yaml +++ /dev/null @@ -1,142 +0,0 @@ -{{- if and .Values.alertmanager.enabled (not .Values.alertmanager.statefulSet.enabled) -}} -apiVersion: {{ template "prometheus.deployment.apiVersion" . }} -kind: Deployment -metadata: - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} - name: {{ template "prometheus.alertmanager.fullname" . }} -spec: - selector: - matchLabels: - {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} - replicas: {{ .Values.alertmanager.replicaCount }} - {{- if .Values.alertmanager.strategy }} - strategy: -{{ toYaml .Values.alertmanager.strategy | indent 4 }} - {{- if eq .Values.alertmanager.strategy.type "Recreate" }} - rollingUpdate: null - {{- end }} - {{- end }} - template: - metadata: - {{- if .Values.alertmanager.podAnnotations }} - annotations: -{{ toYaml .Values.alertmanager.podAnnotations | indent 8 }} - {{- end }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 8 }} - {{- if .Values.alertmanager.podLabels}} - {{ toYaml .Values.alertmanager.podLabels | nindent 8 }} - {{- end}} - spec: -{{- if .Values.alertmanager.schedulerName }} - schedulerName: "{{ .Values.alertmanager.schedulerName }}" -{{- end }} - serviceAccountName: {{ template "prometheus.serviceAccountName.alertmanager" . }} -{{- if .Values.alertmanager.priorityClassName }} - priorityClassName: "{{ .Values.alertmanager.priorityClassName }}" -{{- end }} - containers: - - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }} - image: "{{ .Values.alertmanager.image.repository }}:{{ .Values.alertmanager.image.tag }}" - imagePullPolicy: "{{ .Values.alertmanager.image.pullPolicy }}" - env: - {{- range $key, $value := .Values.alertmanager.extraEnv }} - - name: {{ $key }} - value: {{ $value }} - {{- end }} - - name: POD_IP - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: status.podIP - args: - - --config.file=/etc/config/{{ .Values.alertmanager.configFileName }} - - --storage.path={{ .Values.alertmanager.persistentVolume.mountPath }} - - --cluster.advertise-address=$(POD_IP):6783 - {{- range $key, $value := .Values.alertmanager.extraArgs }} - - --{{ $key }}={{ $value }} - {{- end }} - {{- if .Values.alertmanager.baseURL }} - - --web.external-url={{ .Values.alertmanager.baseURL }} - {{- end }} - - ports: - - containerPort: 9093 - readinessProbe: - httpGet: - path: {{ .Values.alertmanager.prefixURL }}/-/ready - port: 9093 - initialDelaySeconds: 30 - timeoutSeconds: 30 - resources: -{{ toYaml .Values.alertmanager.resources | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/config - - name: storage-volume - mountPath: "{{ .Values.alertmanager.persistentVolume.mountPath }}" - subPath: "{{ .Values.alertmanager.persistentVolume.subPath }}" - {{- range .Values.alertmanager.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - - {{- if .Values.configmapReload.alertmanager.enabled }} - - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }}-{{ .Values.configmapReload.alertmanager.name }} - image: "{{ .Values.configmapReload.alertmanager.image.repository }}:{{ .Values.configmapReload.alertmanager.image.tag }}" - imagePullPolicy: "{{ .Values.configmapReload.alertmanager.image.pullPolicy }}" - args: - - --volume-dir=/etc/config - - --webhook-url=http://127.0.0.1:9093{{ .Values.alertmanager.prefixURL }}/-/reload - resources: -{{ toYaml .Values.configmapReload.alertmanager.resources | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/config - readOnly: true - {{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: - {{ toYaml .Values.imagePullSecrets | indent 2 }} - {{- end }} - {{- if .Values.alertmanager.nodeSelector }} - nodeSelector: -{{ toYaml .Values.alertmanager.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.alertmanager.securityContext }} - securityContext: -{{ toYaml .Values.alertmanager.securityContext | indent 8 }} - {{- end }} - {{- if .Values.alertmanager.tolerations }} - tolerations: -{{ toYaml .Values.alertmanager.tolerations | indent 8 }} - {{- end }} - {{- if .Values.alertmanager.affinity }} - affinity: -{{ toYaml .Values.alertmanager.affinity | indent 8 }} - {{- end }} - volumes: - - name: config-volume - {{- if empty .Values.alertmanager.configFromSecret }} - configMap: - name: {{ if .Values.alertmanager.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.alertmanager.configMapOverrideName }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} - {{- else }} - secret: - secretName: {{ .Values.alertmanager.configFromSecret }} - {{- end }} - {{- range .Values.alertmanager.extraSecretMounts }} - - name: {{ .name }} - secret: - secretName: {{ .secretName }} - {{- end }} - - name: storage-volume - {{- if .Values.alertmanager.persistentVolume.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.alertmanager.persistentVolume.existingClaim }}{{ .Values.alertmanager.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} - {{- else }} - emptyDir: {} - {{- end -}} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-ingress.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-ingress.yaml deleted file mode 100644 index 9883054fb97..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-ingress.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.ingress.enabled -}} -{{- $releaseName := .Release.Name -}} -{{- $serviceName := include "prometheus.alertmanager.fullname" . }} -{{- $servicePort := .Values.alertmanager.service.servicePort -}} -{{- $extraPaths := .Values.alertmanager.ingress.extraPaths -}} -{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} -apiVersion: networking.k8s.io/v1beta1 -{{ else }} -apiVersion: extensions/v1beta1 -{{ end -}} -kind: Ingress -metadata: -{{- if .Values.alertmanager.ingress.annotations }} - annotations: -{{ toYaml .Values.alertmanager.ingress.annotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} -{{- range $key, $value := .Values.alertmanager.ingress.extraLabels }} - {{ $key }}: {{ $value }} -{{- end }} - name: {{ template "prometheus.alertmanager.fullname" . }} -spec: - rules: - {{- range .Values.alertmanager.ingress.hosts }} - {{- $url := splitList "/" . }} - - host: {{ first $url }} - http: - paths: -{{ if $extraPaths }} -{{ toYaml $extraPaths | indent 10 }} -{{- end }} - - path: /{{ rest $url | join "/" }} - backend: - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end -}} -{{- if .Values.alertmanager.ingress.tls }} - tls: -{{ toYaml .Values.alertmanager.ingress.tls | indent 4 }} - {{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-networkpolicy.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-networkpolicy.yaml deleted file mode 100644 index 0bcbd27d410..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-networkpolicy.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.networkPolicy.enabled -}} -apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} -kind: NetworkPolicy -metadata: - name: {{ template "prometheus.alertmanager.fullname" . }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} -spec: - podSelector: - matchLabels: - {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} - ingress: - - from: - - podSelector: - matchLabels: - {{- include "prometheus.server.matchLabels" . | nindent 12 }} - - ports: - - port: 9093 -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-pdb.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-pdb.yaml deleted file mode 100644 index c38df77a772..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-pdb.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if .Values.alertmanager.podDisruptionBudget.enabled }} -apiVersion: policy/v1beta1 -kind: PodDisruptionBudget -metadata: - name: {{ template "prometheus.alertmanager.fullname" . }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} -spec: - maxUnavailable: {{ .Values.alertmanager.podDisruptionBudget.maxUnavailable }} - selector: - matchLabels: - {{- include "prometheus.alertmanager.labels" . | nindent 6 }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-podsecuritypolicy.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-podsecuritypolicy.yaml deleted file mode 100644 index 70f803336ca..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-podsecuritypolicy.yaml +++ /dev/null @@ -1,48 +0,0 @@ -{{- if .Values.rbac.create }} -{{- if .Values.podSecurityPolicy.enabled }} -apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} -kind: PodSecurityPolicy -metadata: - name: {{ template "prometheus.alertmanager.fullname" . }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} - annotations: -{{- if .Values.alertmanager.podSecurityPolicy.annotations }} -{{ toYaml .Values.alertmanager.podSecurityPolicy.annotations | indent 4 }} -{{- end }} -spec: - privileged: false - allowPrivilegeEscalation: false - requiredDropCapabilities: - - ALL - volumes: - - 'configMap' - - 'persistentVolumeClaim' - - 'emptyDir' - - 'secret' - allowedHostPaths: - - pathPrefix: /etc - readOnly: true - - pathPrefix: {{ .Values.alertmanager.persistentVolume.mountPath }} - hostNetwork: false - hostPID: false - hostIPC: 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: true -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-pvc.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-pvc.yaml deleted file mode 100644 index 400aba5b467..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-pvc.yaml +++ /dev/null @@ -1,32 +0,0 @@ -{{- if not .Values.alertmanager.statefulSet.enabled -}} -{{- if and .Values.alertmanager.enabled .Values.alertmanager.persistentVolume.enabled -}} -{{- if not .Values.alertmanager.persistentVolume.existingClaim -}} -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - {{- if .Values.alertmanager.persistentVolume.annotations }} - annotations: -{{ toYaml .Values.alertmanager.persistentVolume.annotations | indent 4 }} - {{- end }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} - name: {{ template "prometheus.alertmanager.fullname" . }} -spec: - accessModes: -{{ toYaml .Values.alertmanager.persistentVolume.accessModes | indent 4 }} -{{- if .Values.alertmanager.persistentVolume.storageClass }} -{{- if (eq "-" .Values.alertmanager.persistentVolume.storageClass) }} - storageClassName: "" -{{- else }} - storageClassName: "{{ .Values.alertmanager.persistentVolume.storageClass }}" -{{- end }} -{{- end }} -{{- if .Values.alertmanager.persistentVolume.volumeBindingMode }} - volumeBindingModeName: "{{ .Values.alertmanager.persistentVolume.volumeBindingMode }}" -{{- end }} - resources: - requests: - storage: "{{ .Values.alertmanager.persistentVolume.size }}" -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-service-headless.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-service-headless.yaml deleted file mode 100644 index 8d619e89179..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-service-headless.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.statefulSet.enabled -}} -apiVersion: v1 -kind: Service -metadata: -{{- if .Values.alertmanager.statefulSet.headless.annotations }} - annotations: -{{ toYaml .Values.alertmanager.statefulSet.headless.annotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} -{{- if .Values.alertmanager.statefulSet.headless.labels }} -{{ toYaml .Values.alertmanager.statefulSet.headless.labels | indent 4 }} -{{- end }} - name: {{ template "prometheus.alertmanager.fullname" . }}-headless -spec: - clusterIP: None - ports: - - name: http - port: {{ .Values.alertmanager.statefulSet.headless.servicePort }} - protocol: TCP - targetPort: 9093 -{{- if .Values.alertmanager.statefulSet.headless.enableMeshPeer }} - - name: meshpeer - port: 6783 - protocol: TCP - targetPort: 6783 -{{- end }} - selector: - {{- include "prometheus.alertmanager.matchLabels" . | nindent 4 }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-service.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-service.yaml deleted file mode 100644 index 79196432c1c..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-service.yaml +++ /dev/null @@ -1,52 +0,0 @@ -{{- if .Values.alertmanager.enabled -}} -apiVersion: v1 -kind: Service -metadata: -{{- if .Values.alertmanager.service.annotations }} - annotations: -{{ toYaml .Values.alertmanager.service.annotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} -{{- if .Values.alertmanager.service.labels }} -{{ toYaml .Values.alertmanager.service.labels | indent 4 }} -{{- end }} - name: {{ template "prometheus.alertmanager.fullname" . }} -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 }} - ports: - - name: http - port: {{ .Values.alertmanager.service.servicePort }} - protocol: TCP - targetPort: 9093 - {{- if .Values.alertmanager.service.nodePort }} - nodePort: {{ .Values.alertmanager.service.nodePort }} - {{- end }} -{{- if .Values.alertmanager.service.enableMeshPeer }} - - name: meshpeer - port: 6783 - protocol: TCP - targetPort: 6783 -{{- end }} - selector: - {{- include "prometheus.alertmanager.matchLabels" . | nindent 4 }} -{{- if .Values.alertmanager.service.sessionAffinity }} - sessionAffinity: {{ .Values.alertmanager.service.sessionAffinity }} -{{- end }} - type: "{{ .Values.alertmanager.service.type }}" -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-serviceaccount.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-serviceaccount.yaml deleted file mode 100644 index 4ff4558963a..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-serviceaccount.yaml +++ /dev/null @@ -1,8 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.serviceAccounts.alertmanager.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} - name: {{ template "prometheus.serviceAccountName.alertmanager" . }} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/alertmanager-statefulset.yaml b/infra/charts/feast/charts/prometheus/templates/alertmanager-statefulset.yaml deleted file mode 100644 index 1f8272dcfa2..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/alertmanager-statefulset.yaml +++ /dev/null @@ -1,152 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.statefulSet.enabled -}} -apiVersion: apps/v1 -kind: StatefulSet -metadata: - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 4 }} - name: {{ template "prometheus.alertmanager.fullname" . }} -spec: - serviceName: {{ template "prometheus.alertmanager.fullname" . }}-headless - selector: - matchLabels: - {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} - replicas: {{ .Values.alertmanager.replicaCount }} - podManagementPolicy: {{ .Values.alertmanager.statefulSet.podManagementPolicy }} - template: - metadata: - {{- if .Values.alertmanager.podAnnotations }} - annotations: -{{ toYaml .Values.alertmanager.podAnnotations | indent 8 }} - {{- end }} - labels: - {{- include "prometheus.alertmanager.labels" . | nindent 8 }} - spec: -{{- if .Values.alertmanager.affinity }} - affinity: -{{ toYaml .Values.alertmanager.affinity | indent 8 }} -{{- end }} -{{- if .Values.alertmanager.schedulerName }} - schedulerName: "{{ .Values.alertmanager.schedulerName }}" -{{- end }} - serviceAccountName: {{ template "prometheus.serviceAccountName.alertmanager" . }} -{{- if .Values.alertmanager.priorityClassName }} - priorityClassName: "{{ .Values.alertmanager.priorityClassName }}" -{{- end }} - containers: - - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }} - image: "{{ .Values.alertmanager.image.repository }}:{{ .Values.alertmanager.image.tag }}" - imagePullPolicy: "{{ .Values.alertmanager.image.pullPolicy }}" - env: - {{- range $key, $value := .Values.alertmanager.extraEnv }} - - name: {{ $key }} - value: {{ $value }} - {{- end }} - - name: POD_IP - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: status.podIP - args: - - --config.file=/etc/config/alertmanager.yml - - --storage.path={{ .Values.alertmanager.persistentVolume.mountPath }} - - --cluster.advertise-address=$(POD_IP):6783 - {{- if .Values.alertmanager.statefulSet.headless.enableMeshPeer }} - - --cluster.listen-address=0.0.0.0:6783 - {{- range $n := until (.Values.alertmanager.replicaCount | int) }} - - --cluster.peer={{ template "prometheus.alertmanager.fullname" $ }}-{{ $n }}.{{ template "prometheus.alertmanager.fullname" $ }}-headless:6783 - {{- end }} - {{- end }} - {{- range $key, $value := .Values.alertmanager.extraArgs }} - - --{{ $key }}={{ $value }} - {{- end }} - {{- if .Values.alertmanager.baseURL }} - - --web.external-url={{ .Values.alertmanager.baseURL }} - {{- end }} - - ports: - - containerPort: 9093 - readinessProbe: - httpGet: - path: {{ .Values.alertmanager.prefixURL }}/#/status - port: 9093 - initialDelaySeconds: 30 - timeoutSeconds: 30 - resources: -{{ toYaml .Values.alertmanager.resources | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/config - - name: storage-volume - mountPath: "{{ .Values.alertmanager.persistentVolume.mountPath }}" - subPath: "{{ .Values.alertmanager.persistentVolume.subPath }}" - {{- range .Values.alertmanager.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- if .Values.configmapReload.alertmanager.enabled }} - - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }}-{{ .Values.configmapReload.alertmanager.name }} - image: "{{ .Values.configmapReload.alertmanager.image.repository }}:{{ .Values.configmapReload.alertmanager.image.tag }}" - imagePullPolicy: "{{ .Values.configmapReload.alertmanager.image.pullPolicy }}" - args: - - --volume-dir=/etc/config - - --webhook-url=http://localhost:9093{{ .Values.alertmanager.prefixURL }}/-/reload - resources: -{{ toYaml .Values.configmapReload.alertmanager.resources | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/config - readOnly: true - {{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: - {{ toYaml .Values.imagePullSecrets | indent 2 }} - {{- end }} - {{- if .Values.alertmanager.nodeSelector }} - nodeSelector: -{{ toYaml .Values.alertmanager.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.alertmanager.securityContext }} - securityContext: -{{ toYaml .Values.alertmanager.securityContext | indent 8 }} - {{- end }} - {{- if .Values.alertmanager.tolerations }} - tolerations: -{{ toYaml .Values.alertmanager.tolerations | indent 8 }} - {{- end }} - volumes: - - name: config-volume - configMap: - name: {{ if .Values.alertmanager.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.alertmanager.configMapOverrideName }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} - {{- range .Values.alertmanager.extraSecretMounts }} - - name: {{ .name }} - secret: - secretName: {{ .secretName }} - {{- end }} -{{- if .Values.alertmanager.persistentVolume.enabled }} - volumeClaimTemplates: - - metadata: - name: storage-volume - {{- if .Values.alertmanager.persistentVolume.annotations }} - annotations: -{{ toYaml .Values.alertmanager.persistentVolume.annotations | indent 10 }} - {{- end }} - spec: - accessModes: -{{ toYaml .Values.alertmanager.persistentVolume.accessModes | indent 10 }} - resources: - requests: - storage: "{{ .Values.alertmanager.persistentVolume.size }}" - {{- if .Values.server.persistentVolume.storageClass }} - {{- if (eq "-" .Values.server.persistentVolume.storageClass) }} - storageClassName: "" - {{- else }} - storageClassName: "{{ .Values.alertmanager.persistentVolume.storageClass }}" - {{- end }} - {{- end }} -{{- else }} - - name: storage-volume - emptyDir: {} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-daemonset.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-daemonset.yaml deleted file mode 100644 index 478f10a9bae..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/node-exporter-daemonset.yaml +++ /dev/null @@ -1,116 +0,0 @@ -{{- if .Values.nodeExporter.enabled -}} -apiVersion: {{ template "prometheus.daemonset.apiVersion" . }} -kind: DaemonSet -metadata: -{{- if .Values.nodeExporter.deploymentAnnotations }} - annotations: -{{ toYaml .Values.nodeExporter.deploymentAnnotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} - name: {{ template "prometheus.nodeExporter.fullname" . }} -spec: - selector: - matchLabels: - {{- include "prometheus.nodeExporter.matchLabels" . | nindent 6 }} - {{- if .Values.nodeExporter.updateStrategy }} - updateStrategy: -{{ toYaml .Values.nodeExporter.updateStrategy | indent 4 }} - {{- end }} - template: - metadata: - {{- if .Values.nodeExporter.podAnnotations }} - annotations: -{{ toYaml .Values.nodeExporter.podAnnotations | indent 8 }} - {{- end }} - labels: - {{- include "prometheus.nodeExporter.labels" . | nindent 8 }} -{{- if .Values.nodeExporter.pod.labels }} -{{ toYaml .Values.nodeExporter.pod.labels | indent 8 }} -{{- end }} - spec: - serviceAccountName: {{ template "prometheus.serviceAccountName.nodeExporter" . }} -{{- if .Values.nodeExporter.priorityClassName }} - priorityClassName: "{{ .Values.nodeExporter.priorityClassName }}" -{{- end }} - containers: - - name: {{ template "prometheus.name" . }}-{{ .Values.nodeExporter.name }} - image: "{{ .Values.nodeExporter.image.repository }}:{{ .Values.nodeExporter.image.tag }}" - imagePullPolicy: "{{ .Values.nodeExporter.image.pullPolicy }}" - args: - - --path.procfs=/host/proc - - --path.sysfs=/host/sys - {{- range $key, $value := .Values.nodeExporter.extraArgs }} - {{- if $value }} - - --{{ $key }}={{ $value }} - {{- else }} - - --{{ $key }} - {{- end }} - {{- end }} - ports: - - name: metrics - containerPort: 9100 - hostPort: {{ .Values.nodeExporter.service.hostPort }} - resources: -{{ toYaml .Values.nodeExporter.resources | indent 12 }} - volumeMounts: - - name: proc - mountPath: /host/proc - readOnly: true - - name: sys - mountPath: /host/sys - readOnly: true - {{- range .Values.nodeExporter.extraHostPathMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - readOnly: {{ .readOnly }} - {{- if .mountPropagation }} - mountPropagation: {{ .mountPropagation }} - {{- end }} - {{- end }} - {{- range .Values.nodeExporter.extraConfigmapMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: - {{ toYaml .Values.imagePullSecrets | indent 2 }} - {{- end }} - {{- if .Values.nodeExporter.hostNetwork }} - hostNetwork: true - {{- end }} - {{- if .Values.nodeExporter.hostPID }} - hostPID: true - {{- end }} - {{- if .Values.nodeExporter.tolerations }} - tolerations: -{{ toYaml .Values.nodeExporter.tolerations | indent 8 }} - {{- end }} - {{- if .Values.nodeExporter.nodeSelector }} - nodeSelector: -{{ toYaml .Values.nodeExporter.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.nodeExporter.securityContext }} - securityContext: -{{ toYaml .Values.nodeExporter.securityContext | indent 8 }} - {{- end }} - volumes: - - name: proc - hostPath: - path: /proc - - name: sys - hostPath: - path: /sys - {{- range .Values.nodeExporter.extraHostPathMounts }} - - name: {{ .name }} - hostPath: - path: {{ .hostPath }} - {{- end }} - {{- range .Values.nodeExporter.extraConfigmapMounts }} - - name: {{ .name }} - configMap: - name: {{ .configMap }} - {{- end }} - -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-podsecuritypolicy.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-podsecuritypolicy.yaml deleted file mode 100644 index 825794b4e32..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/node-exporter-podsecuritypolicy.yaml +++ /dev/null @@ -1,55 +0,0 @@ -{{- if and .Values.nodeExporter.enabled .Values.rbac.create }} -{{- if .Values.podSecurityPolicy.enabled }} -apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} -kind: PodSecurityPolicy -metadata: - name: {{ template "prometheus.nodeExporter.fullname" . }} - labels: - {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} - annotations: -{{- if .Values.nodeExporter.podSecurityPolicy.annotations }} -{{ toYaml .Values.nodeExporter.podSecurityPolicy.annotations | indent 4 }} -{{- end }} -spec: - privileged: false - allowPrivilegeEscalation: false - requiredDropCapabilities: - - ALL - volumes: - - 'configMap' - - 'hostPath' - - 'secret' - allowedHostPaths: - - pathPrefix: /proc - readOnly: true - - pathPrefix: /sys - readOnly: true - {{- range .Values.nodeExporter.extraHostPathMounts }} - - pathPrefix: {{ .hostPath }} - readOnly: {{ .readOnly }} - {{- end }} - hostNetwork: {{ .Values.nodeExporter.hostNetwork }} - hostPID: {{ .Values.nodeExporter.hostPID }} - hostIPC: 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 - hostPorts: - - min: 1 - max: 65535 -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-role.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-role.yaml deleted file mode 100644 index 49a6874b37b..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/node-exporter-role.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.nodeExporter.enabled .Values.rbac.create }} -{{- if or (default .Values.nodeExporter.podSecurityPolicy.enabled false) (.Values.podSecurityPolicy.enabled) }} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: Role -metadata: - name: {{ template "prometheus.nodeExporter.fullname" . }} - labels: - {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} -rules: -- apiGroups: ['extensions'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "prometheus.nodeExporter.fullname" . }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-rolebinding.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-rolebinding.yaml deleted file mode 100644 index e56e5ff4144..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/node-exporter-rolebinding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if and .Values.nodeExporter.enabled .Values.rbac.create }} -{{- if .Values.podSecurityPolicy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "prometheus.nodeExporter.fullname" . }} - labels: - {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: Role - name: {{ template "prometheus.nodeExporter.fullname" . }} - apiGroup: rbac.authorization.k8s.io -subjects: -- kind: ServiceAccount - name: {{ template "prometheus.serviceAccountName.nodeExporter" . }} - namespace: {{ .Release.Namespace }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-service.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-service.yaml deleted file mode 100644 index 55c683b6aba..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/node-exporter-service.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if .Values.nodeExporter.enabled -}} -apiVersion: v1 -kind: Service -metadata: -{{- if .Values.nodeExporter.service.annotations }} - annotations: -{{ toYaml .Values.nodeExporter.service.annotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} -{{- if .Values.nodeExporter.service.labels }} -{{ toYaml .Values.nodeExporter.service.labels | indent 4 }} -{{- end }} - name: {{ template "prometheus.nodeExporter.fullname" . }} -spec: -{{- if .Values.nodeExporter.service.clusterIP }} - clusterIP: {{ .Values.nodeExporter.service.clusterIP }} -{{- end }} -{{- if .Values.nodeExporter.service.externalIPs }} - externalIPs: -{{ toYaml .Values.nodeExporter.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.nodeExporter.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.nodeExporter.service.loadBalancerIP }} -{{- end }} -{{- if .Values.nodeExporter.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.nodeExporter.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} - ports: - - name: metrics - port: {{ .Values.nodeExporter.service.servicePort }} - protocol: TCP - targetPort: 9100 - selector: - {{- include "prometheus.nodeExporter.matchLabels" . | nindent 4 }} - type: "{{ .Values.nodeExporter.service.type }}" -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/node-exporter-serviceaccount.yaml b/infra/charts/feast/charts/prometheus/templates/node-exporter-serviceaccount.yaml deleted file mode 100644 index a922b238bf8..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/node-exporter-serviceaccount.yaml +++ /dev/null @@ -1,8 +0,0 @@ -{{- if and .Values.nodeExporter.enabled .Values.serviceAccounts.nodeExporter.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} - name: {{ template "prometheus.serviceAccountName.nodeExporter" . }} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrole.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrole.yaml deleted file mode 100644 index f4393c921a5..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrole.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.pushgateway.enabled .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} - name: {{ template "prometheus.pushgateway.fullname" . }} -rules: -{{- if .Values.podSecurityPolicy.enabled }} - - apiGroups: - - extensions - resources: - - podsecuritypolicies - verbs: - - use - resourceNames: - - {{ template "prometheus.pushgateway.fullname" . }} -{{- else }} - [] -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrolebinding.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrolebinding.yaml deleted file mode 100644 index bcbaccb29b0..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-clusterrolebinding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.pushgateway.enabled .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} - name: {{ template "prometheus.pushgateway.fullname" . }} -subjects: - - kind: ServiceAccount - name: {{ template "prometheus.serviceAccountName.pushgateway" . }} - namespace: {{ .Release.Namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "prometheus.pushgateway.fullname" . }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-deployment.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-deployment.yaml deleted file mode 100644 index a681eda382c..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-deployment.yaml +++ /dev/null @@ -1,100 +0,0 @@ -{{- if .Values.pushgateway.enabled -}} -apiVersion: {{ template "prometheus.deployment.apiVersion" . }} -kind: Deployment -metadata: - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} - name: {{ template "prometheus.pushgateway.fullname" . }} -spec: - selector: - {{- if .Values.schedulerName }} - schedulerName: "{{ .Values.schedulerName }}" - {{- end }} - matchLabels: - {{- include "prometheus.pushgateway.matchLabels" . | nindent 6 }} - replicas: {{ .Values.pushgateway.replicaCount }} - {{- if .Values.pushgateway.strategy }} - strategy: -{{ toYaml .Values.pushgateway.strategy | indent 4 }} - {{- if eq .Values.pushgateway.strategy.type "Recreate" }} - rollingUpdate: null - {{- end }} - {{- end }} - template: - metadata: - {{- if .Values.pushgateway.podAnnotations }} - annotations: -{{ toYaml .Values.pushgateway.podAnnotations | indent 8 }} - {{- end }} - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 8 }} - spec: - serviceAccountName: {{ template "prometheus.serviceAccountName.pushgateway" . }} -{{- if .Values.pushgateway.priorityClassName }} - priorityClassName: "{{ .Values.pushgateway.priorityClassName }}" -{{- end }} - containers: - - name: {{ template "prometheus.name" . }}-{{ .Values.pushgateway.name }} - image: "{{ .Values.pushgateway.image.repository }}:{{ .Values.pushgateway.image.tag }}" - imagePullPolicy: "{{ .Values.pushgateway.image.pullPolicy }}" - args: - {{- range $key, $value := .Values.pushgateway.extraArgs }} - - --{{ $key }}={{ $value }} - {{- end }} - ports: - - containerPort: 9091 - livenessProbe: - httpGet: - {{- if (index .Values "pushgateway" "extraArgs" "web.route-prefix") }} - path: /{{ index .Values "pushgateway" "extraArgs" "web.route-prefix" }}/-/healthy - {{- else }} - path: /-/healthy - {{- end }} - port: 9091 - initialDelaySeconds: 10 - timeoutSeconds: 10 - readinessProbe: - httpGet: - {{- if (index .Values "pushgateway" "extraArgs" "web.route-prefix") }} - path: /{{ index .Values "pushgateway" "extraArgs" "web.route-prefix" }}/-/ready - {{- else }} - path: /-/ready - {{- end }} - port: 9091 - initialDelaySeconds: 10 - timeoutSeconds: 10 - resources: -{{ toYaml .Values.pushgateway.resources | indent 12 }} - {{- if .Values.pushgateway.persistentVolume.enabled }} - volumeMounts: - - name: storage-volume - mountPath: "{{ .Values.pushgateway.persistentVolume.mountPath }}" - subPath: "{{ .Values.pushgateway.persistentVolume.subPath }}" - {{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: - {{ toYaml .Values.imagePullSecrets | indent 2 }} - {{- end }} - {{- if .Values.pushgateway.nodeSelector }} - nodeSelector: -{{ toYaml .Values.pushgateway.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.pushgateway.securityContext }} - securityContext: -{{ toYaml .Values.pushgateway.securityContext | indent 8 }} - {{- end }} - {{- if .Values.pushgateway.tolerations }} - tolerations: -{{ toYaml .Values.pushgateway.tolerations | indent 8 }} - {{- end }} - {{- if .Values.pushgateway.affinity }} - affinity: -{{ toYaml .Values.pushgateway.affinity | indent 8 }} - {{- end }} - {{- if .Values.pushgateway.persistentVolume.enabled }} - volumes: - - name: storage-volume - persistentVolumeClaim: - claimName: {{ if .Values.pushgateway.persistentVolume.existingClaim }}{{ .Values.pushgateway.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.pushgateway.fullname" . }}{{- end }} - {{- end -}} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-ingress.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-ingress.yaml deleted file mode 100644 index 60c6d7455ee..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-ingress.yaml +++ /dev/null @@ -1,39 +0,0 @@ -{{- if and .Values.pushgateway.enabled .Values.pushgateway.ingress.enabled -}} -{{- $releaseName := .Release.Name -}} -{{- $serviceName := include "prometheus.pushgateway.fullname" . }} -{{- $servicePort := .Values.pushgateway.service.servicePort -}} -{{- $extraPaths := .Values.pushgateway.ingress.extraPaths -}} -{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} -apiVersion: networking.k8s.io/v1beta1 -{{ else }} -apiVersion: extensions/v1beta1 -{{ end -}} -kind: Ingress -metadata: -{{- if .Values.pushgateway.ingress.annotations }} - annotations: -{{ toYaml .Values.pushgateway.ingress.annotations | indent 4}} -{{- end }} - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} - name: {{ template "prometheus.pushgateway.fullname" . }} -spec: - rules: - {{- range .Values.pushgateway.ingress.hosts }} - {{- $url := splitList "/" . }} - - host: {{ first $url }} - http: - paths: -{{ if $extraPaths }} -{{ toYaml $extraPaths | indent 10 }} -{{- end }} - - path: /{{ rest $url | join "/" }} - backend: - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end -}} -{{- if .Values.pushgateway.ingress.tls }} - tls: -{{ toYaml .Values.pushgateway.ingress.tls | indent 4 }} - {{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-networkpolicy.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-networkpolicy.yaml deleted file mode 100644 index e8f6ab82927..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-networkpolicy.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if and .Values.pushgateway.enabled .Values.networkPolicy.enabled -}} -apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} -kind: NetworkPolicy -metadata: - name: {{ template "prometheus.pushgateway.fullname" . }} - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} -spec: - podSelector: - matchLabels: - {{- include "prometheus.pushgateway.matchLabels" . | nindent 6 }} - ingress: - - from: - - podSelector: - matchLabels: - {{- include "prometheus.server.matchLabels" . | nindent 12 }} - - ports: - - port: 9091 -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-pdb.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-pdb.yaml deleted file mode 100644 index e9910a5c88b..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-pdb.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if .Values.pushgateway.podDisruptionBudget.enabled }} -apiVersion: policy/v1beta1 -kind: PodDisruptionBudget -metadata: - name: {{ template "prometheus.pushgateway.fullname" . }} - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} -spec: - maxUnavailable: {{ .Values.pushgateway.podDisruptionBudget.maxUnavailable }} - selector: - matchLabels: - {{- include "prometheus.pushgateway.labels" . | nindent 6 }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-podsecuritypolicy.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-podsecuritypolicy.yaml deleted file mode 100644 index dd3829df295..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-podsecuritypolicy.yaml +++ /dev/null @@ -1,44 +0,0 @@ -{{- if .Values.rbac.create }} -{{- if .Values.podSecurityPolicy.enabled }} -apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} -kind: PodSecurityPolicy -metadata: - name: {{ template "prometheus.pushgateway.fullname" . }} - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} - annotations: -{{- if .Values.pushgateway.podSecurityPolicy.annotations }} -{{ toYaml .Values.pushgateway.podSecurityPolicy.annotations | indent 4 }} -{{- end }} -spec: - privileged: false - allowPrivilegeEscalation: false - requiredDropCapabilities: - - ALL - volumes: - - 'persistentVolumeClaim' - - 'secret' - allowedHostPaths: - - pathPrefix: {{ .Values.pushgateway.persistentVolume.mountPath }} - hostNetwork: false - hostPID: false - hostIPC: 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: true -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-pvc.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-pvc.yaml deleted file mode 100644 index ba16a37af23..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-pvc.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.pushgateway.persistentVolume.enabled -}} -{{- if not .Values.pushgateway.persistentVolume.existingClaim -}} -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - {{- if .Values.pushgateway.persistentVolume.annotations }} - annotations: -{{ toYaml .Values.pushgateway.persistentVolume.annotations | indent 4 }} - {{- end }} - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} - name: {{ template "prometheus.pushgateway.fullname" . }} -spec: - accessModes: -{{ toYaml .Values.pushgateway.persistentVolume.accessModes | indent 4 }} -{{- if .Values.pushgateway.persistentVolume.storageClass }} -{{- if (eq "-" .Values.pushgateway.persistentVolume.storageClass) }} - storageClassName: "" -{{- else }} - storageClassName: "{{ .Values.pushgateway.persistentVolume.storageClass }}" -{{- end }} -{{- end }} -{{- if .Values.pushgateway.persistentVolume.volumeBindingMode }} - volumeBindingModeName: "{{ .Values.pushgateway.persistentVolume.volumeBindingMode }}" -{{- end }} - resources: - requests: - storage: "{{ .Values.pushgateway.persistentVolume.size }}" -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-service.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-service.yaml deleted file mode 100644 index e84771d8bb4..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-service.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if .Values.pushgateway.enabled -}} -apiVersion: v1 -kind: Service -metadata: -{{- if .Values.pushgateway.service.annotations }} - annotations: -{{ toYaml .Values.pushgateway.service.annotations | indent 4}} -{{- end }} - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} -{{- if .Values.pushgateway.service.labels }} -{{ toYaml .Values.pushgateway.service.labels | indent 4}} -{{- end }} - name: {{ template "prometheus.pushgateway.fullname" . }} -spec: -{{- if .Values.pushgateway.service.clusterIP }} - clusterIP: {{ .Values.pushgateway.service.clusterIP }} -{{- end }} -{{- if .Values.pushgateway.service.externalIPs }} - externalIPs: -{{ toYaml .Values.pushgateway.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.pushgateway.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.pushgateway.service.loadBalancerIP }} -{{- end }} -{{- if .Values.pushgateway.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.pushgateway.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} - ports: - - name: http - port: {{ .Values.pushgateway.service.servicePort }} - protocol: TCP - targetPort: 9091 - selector: - {{- include "prometheus.pushgateway.matchLabels" . | nindent 4 }} - type: "{{ .Values.pushgateway.service.type }}" -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/pushgateway-serviceaccount.yaml b/infra/charts/feast/charts/prometheus/templates/pushgateway-serviceaccount.yaml deleted file mode 100644 index 1596a28f9c7..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/pushgateway-serviceaccount.yaml +++ /dev/null @@ -1,8 +0,0 @@ -{{- if and .Values.pushgateway.enabled .Values.serviceAccounts.pushgateway.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "prometheus.pushgateway.labels" . | nindent 4 }} - name: {{ template "prometheus.serviceAccountName.pushgateway" . }} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-clusterrole.yaml b/infra/charts/feast/charts/prometheus/templates/server-clusterrole.yaml deleted file mode 100644 index c0c0585b9ce..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-clusterrole.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- if and .Values.server.enabled .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - name: {{ template "prometheus.server.fullname" . }} -rules: -{{- if .Values.podSecurityPolicy.enabled }} - - apiGroups: - - extensions - resources: - - podsecuritypolicies - verbs: - - use - resourceNames: - - {{ template "prometheus.server.fullname" . }} -{{- end }} - - apiGroups: - - "" - resources: - - nodes - - nodes/proxy - - nodes/metrics - - services - - endpoints - - pods - - ingresses - - configmaps - verbs: - - get - - list - - watch - - apiGroups: - - "extensions" - resources: - - ingresses/status - - ingresses - verbs: - - get - - list - - watch - - nonResourceURLs: - - "/metrics" - verbs: - - get -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-clusterrolebinding.yaml b/infra/charts/feast/charts/prometheus/templates/server-clusterrolebinding.yaml deleted file mode 100644 index 1196ce3f2d1..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-clusterrolebinding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.server.enabled .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - name: {{ template "prometheus.server.fullname" . }} -subjects: - - kind: ServiceAccount - name: {{ template "prometheus.serviceAccountName.server" . }} - namespace: {{ .Release.Namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "prometheus.server.fullname" . }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-configmap.yaml b/infra/charts/feast/charts/prometheus/templates/server-configmap.yaml deleted file mode 100644 index ac79fdf2fb6..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-configmap.yaml +++ /dev/null @@ -1,81 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if (empty .Values.server.configMapOverrideName) -}} -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - name: {{ template "prometheus.server.fullname" . }} -data: -{{- $root := . -}} -{{- range $key, $value := .Values.serverFiles }} - {{ $key }}: | -{{- if eq $key "prometheus.yml" }} - global: -{{ $root.Values.server.global | toYaml | trimSuffix "\n" | indent 6 }} -{{- if $root.Values.server.remoteWrite }} - remote_write: -{{ $root.Values.server.remoteWrite | toYaml | indent 4 }} -{{- end }} -{{- if $root.Values.server.remoteRead }} - remote_read: -{{ $root.Values.server.remoteRead | toYaml | indent 4 }} -{{- end }} -{{- end }} -{{- if eq $key "alerts" }} -{{- if and (not (empty $value)) (empty $value.groups) }} - groups: -{{- range $ruleKey, $ruleValue := $value }} - - name: {{ $ruleKey -}}.rules - rules: -{{ $ruleValue | toYaml | trimSuffix "\n" | indent 6 }} -{{- end }} -{{- else }} -{{ toYaml $value | indent 4 }} -{{- end }} -{{- else }} -{{ toYaml $value | default "{}" | indent 4 }} -{{- end }} -{{- if eq $key "prometheus.yml" -}} -{{- if $root.Values.extraScrapeConfigs }} -{{ tpl $root.Values.extraScrapeConfigs $root | indent 4 }} -{{- end -}} -{{- if or ($root.Values.alertmanager.enabled) ($root.Values.server.alertmanagers) }} - alerting: -{{- if $root.Values.alertRelabelConfigs }} -{{ $root.Values.alertRelabelConfigs | toYaml | trimSuffix "\n" | indent 6 }} -{{- end }} - alertmanagers: -{{- if $root.Values.server.alertmanagers }} -{{ toYaml $root.Values.server.alertmanagers | indent 8 }} -{{- else }} - - kubernetes_sd_configs: - - role: pod - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - {{- if $root.Values.alertmanager.prefixURL }} - path_prefix: {{ $root.Values.alertmanager.prefixURL }} - {{- end }} - relabel_configs: - - source_labels: [__meta_kubernetes_namespace] - regex: {{ $root.Release.Namespace }} - action: keep - - source_labels: [__meta_kubernetes_pod_label_app] - regex: {{ template "prometheus.name" $root }} - action: keep - - source_labels: [__meta_kubernetes_pod_label_component] - regex: alertmanager - action: keep - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_probe] - regex: {{ index $root.Values.alertmanager.podAnnotations "prometheus.io/probe" | default ".*" }} - action: keep - - source_labels: [__meta_kubernetes_pod_container_port_number] - regex: - action: drop -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-deployment.yaml b/infra/charts/feast/charts/prometheus/templates/server-deployment.yaml deleted file mode 100644 index 79746a238e6..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-deployment.yaml +++ /dev/null @@ -1,217 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if not .Values.server.statefulSet.enabled -}} -apiVersion: {{ template "prometheus.deployment.apiVersion" . }} -kind: Deployment -metadata: -{{- if .Values.server.deploymentAnnotations }} - annotations: -{{ toYaml .Values.server.deploymentAnnotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - name: {{ template "prometheus.server.fullname" . }} -spec: - selector: - matchLabels: - {{- include "prometheus.server.matchLabels" . | nindent 6 }} - replicas: {{ .Values.server.replicaCount }} - {{- if .Values.server.strategy }} - strategy: -{{ toYaml .Values.server.strategy | indent 4 }} - {{- if eq .Values.server.strategy.type "Recreate" }} - rollingUpdate: null - {{- end }} - {{- end }} - template: - metadata: - {{- if .Values.server.podAnnotations }} - annotations: -{{ toYaml .Values.server.podAnnotations | indent 8 }} - {{- end }} - labels: - {{- include "prometheus.server.labels" . | nindent 8 }} - {{- if .Values.server.podLabels}} - {{ toYaml .Values.server.podLabels | nindent 8 }} - {{- end}} - spec: -{{- if .Values.server.priorityClassName }} - priorityClassName: "{{ .Values.server.priorityClassName }}" -{{- end }} -{{- if .Values.server.schedulerName }} - schedulerName: "{{ .Values.server.schedulerName }}" -{{- end }} - serviceAccountName: {{ template "prometheus.serviceAccountName.server" . }} - {{- if .Values.server.extraInitContainers }} - initContainers: -{{ toYaml .Values.server.extraInitContainers | indent 8 }} - {{- end }} - containers: - {{- if .Values.configmapReload.prometheus.enabled }} - - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }}-{{ .Values.configmapReload.prometheus.name }} - image: "{{ .Values.configmapReload.prometheus.image.repository }}:{{ .Values.configmapReload.prometheus.image.tag }}" - imagePullPolicy: "{{ .Values.configmapReload.prometheus.image.pullPolicy }}" - args: - - --volume-dir=/etc/config - - --webhook-url=http://127.0.0.1:9090{{ .Values.server.prefixURL }}/-/reload - {{- range $key, $value := .Values.configmapReload.prometheus.extraArgs }} - - --{{ $key }}={{ $value }} - {{- end }} - {{- range .Values.configmapReload.prometheus.extraVolumeDirs }} - - --volume-dir={{ . }} - {{- end }} - resources: -{{ toYaml .Values.configmapReload.prometheus.resources | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/config - readOnly: true - {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} - - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- end }} - - - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }} - image: "{{ .Values.server.image.repository }}:{{ .Values.server.image.tag }}" - imagePullPolicy: "{{ .Values.server.image.pullPolicy }}" - {{- if .Values.server.env }} - env: -{{ toYaml .Values.server.env | indent 12}} - {{- end }} - args: - {{- if .Values.server.retention }} - - --storage.tsdb.retention.time={{ .Values.server.retention }} - {{- end }} - - --config.file={{ .Values.server.configPath }} - - --storage.tsdb.path={{ .Values.server.persistentVolume.mountPath }} - - --web.console.libraries=/etc/prometheus/console_libraries - - --web.console.templates=/etc/prometheus/consoles - {{- range .Values.server.extraFlags }} - - --{{ . }} - {{- end }} - {{- if .Values.server.baseURL }} - - --web.external-url={{ .Values.server.baseURL }} - {{- end }} - - {{- range $key, $value := .Values.server.extraArgs }} - - --{{ $key }}={{ $value }} - {{- end }} - ports: - - containerPort: 9090 - readinessProbe: - httpGet: - path: {{ .Values.server.prefixURL }}/-/ready - port: 9090 - initialDelaySeconds: {{ .Values.server.readinessProbeInitialDelay }} - timeoutSeconds: {{ .Values.server.readinessProbeTimeout }} - failureThreshold: {{ .Values.server.readinessProbeFailureThreshold }} - successThreshold: {{ .Values.server.readinessProbeSuccessThreshold }} - livenessProbe: - httpGet: - path: {{ .Values.server.prefixURL }}/-/healthy - port: 9090 - initialDelaySeconds: {{ .Values.server.livenessProbeInitialDelay }} - timeoutSeconds: {{ .Values.server.livenessProbeTimeout }} - failureThreshold: {{ .Values.server.livenessProbeFailureThreshold }} - successThreshold: {{ .Values.server.livenessProbeSuccessThreshold }} - resources: -{{ toYaml .Values.server.resources | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/config - - name: storage-volume - mountPath: {{ .Values.server.persistentVolume.mountPath }} - subPath: "{{ .Values.server.persistentVolume.subPath }}" - {{- range .Values.server.extraHostPathMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- range .Values.server.extraConfigmapMounts }} - - name: {{ $.Values.server.name }}-{{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- range .Values.server.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- if .Values.server.extraVolumeMounts }} - {{ toYaml .Values.server.extraVolumeMounts | nindent 12 }} - {{- end }} - {{- if .Values.server.sidecarContainers }} - {{- toYaml .Values.server.sidecarContainers | nindent 8 }} - {{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: - {{ toYaml .Values.imagePullSecrets | indent 2 }} - {{- end }} - {{- if .Values.server.nodeSelector }} - nodeSelector: -{{ toYaml .Values.server.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.server.securityContext }} - securityContext: -{{ toYaml .Values.server.securityContext | indent 8 }} - {{- end }} - {{- if .Values.server.tolerations }} - tolerations: -{{ toYaml .Values.server.tolerations | indent 8 }} - {{- end }} - {{- if .Values.server.affinity }} - affinity: -{{ toYaml .Values.server.affinity | indent 8 }} - {{- end }} - terminationGracePeriodSeconds: {{ .Values.server.terminationGracePeriodSeconds }} - volumes: - - name: config-volume - configMap: - name: {{ if .Values.server.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.server.configMapOverrideName }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} - - name: storage-volume - {{- if .Values.server.persistentVolume.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.server.persistentVolume.existingClaim }}{{ .Values.server.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} - {{- else }} - emptyDir: - {{- if .Values.server.emptyDir.sizeLimit }} - sizeLimit: {{ .Values.server.emptyDir.sizeLimit }} - {{- else }} - {} - {{- end -}} - {{- end -}} -{{- if .Values.server.extraVolumes }} -{{ toYaml .Values.server.extraVolumes | indent 8}} -{{- end }} - {{- range .Values.server.extraHostPathMounts }} - - name: {{ .name }} - hostPath: - path: {{ .hostPath }} - {{- end }} - {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} - - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} - configMap: - name: {{ .configMap }} - {{- end }} - {{- range .Values.server.extraConfigmapMounts }} - - name: {{ $.Values.server.name }}-{{ .name }} - configMap: - name: {{ .configMap }} - {{- end }} - {{- range .Values.server.extraSecretMounts }} - - name: {{ .name }} - secret: - secretName: {{ .secretName }} - {{- end }} - {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} - - name: {{ .name }} - configMap: - name: {{ .configMap }} - {{- end }} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-ingress.yaml b/infra/charts/feast/charts/prometheus/templates/server-ingress.yaml deleted file mode 100644 index 16f0a2af748..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-ingress.yaml +++ /dev/null @@ -1,44 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if .Values.server.ingress.enabled -}} -{{- $releaseName := .Release.Name -}} -{{- $serviceName := include "prometheus.server.fullname" . }} -{{- $servicePort := .Values.server.service.servicePort -}} -{{- $extraPaths := .Values.server.ingress.extraPaths -}} -{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} -apiVersion: networking.k8s.io/v1beta1 -{{ else }} -apiVersion: extensions/v1beta1 -{{ end -}} -kind: Ingress -metadata: -{{- if .Values.server.ingress.annotations }} - annotations: -{{ toYaml .Values.server.ingress.annotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} -{{- range $key, $value := .Values.server.ingress.extraLabels }} - {{ $key }}: {{ $value }} -{{- end }} - name: {{ template "prometheus.server.fullname" . }} -spec: - rules: - {{- range .Values.server.ingress.hosts }} - {{- $url := splitList "/" . }} - - host: {{ first $url }} - http: - paths: -{{ if $extraPaths }} -{{ toYaml $extraPaths | indent 10 }} -{{- end }} - - path: /{{ rest $url | join "/" }} - backend: - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end -}} -{{- if .Values.server.ingress.tls }} - tls: -{{ toYaml .Values.server.ingress.tls | indent 4 }} - {{- end -}} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-networkpolicy.yaml b/infra/charts/feast/charts/prometheus/templates/server-networkpolicy.yaml deleted file mode 100644 index 9e10129deb5..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-networkpolicy.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if .Values.networkPolicy.enabled }} -apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} -kind: NetworkPolicy -metadata: - name: {{ template "prometheus.server.fullname" . }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} -spec: - podSelector: - matchLabels: - {{- include "prometheus.server.matchLabels" . | nindent 6 }} - ingress: - - ports: - - port: 9090 -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-pdb.yaml b/infra/charts/feast/charts/prometheus/templates/server-pdb.yaml deleted file mode 100644 index b2447fdba2b..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-pdb.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if .Values.server.podDisruptionBudget.enabled }} -apiVersion: policy/v1beta1 -kind: PodDisruptionBudget -metadata: - name: {{ template "prometheus.server.fullname" . }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} -spec: - maxUnavailable: {{ .Values.server.podDisruptionBudget.maxUnavailable }} - selector: - matchLabels: - {{- include "prometheus.server.labels" . | nindent 6 }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-podsecuritypolicy.yaml b/infra/charts/feast/charts/prometheus/templates/server-podsecuritypolicy.yaml deleted file mode 100644 index a0e15a348d2..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-podsecuritypolicy.yaml +++ /dev/null @@ -1,53 +0,0 @@ -{{- if .Values.rbac.create }} -{{- if .Values.podSecurityPolicy.enabled }} -apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} -kind: PodSecurityPolicy -metadata: - name: {{ template "prometheus.server.fullname" . }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - annotations: -{{- if .Values.server.podSecurityPolicy.annotations }} -{{ toYaml .Values.server.podSecurityPolicy.annotations | indent 4 }} -{{- end }} -spec: - privileged: false - allowPrivilegeEscalation: false - allowedCapabilities: - - 'CHOWN' - volumes: - - 'configMap' - - 'persistentVolumeClaim' - - 'emptyDir' - - 'secret' - - 'hostPath' - allowedHostPaths: - - pathPrefix: /etc - readOnly: true - - pathPrefix: {{ .Values.server.persistentVolume.mountPath }} - {{- range .Values.server.extraHostPathMounts }} - - pathPrefix: {{ .hostPath }} - readOnly: {{ .readOnly }} - {{- end }} - hostNetwork: false - hostPID: false - hostIPC: 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 }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-pvc.yaml b/infra/charts/feast/charts/prometheus/templates/server-pvc.yaml deleted file mode 100644 index 9d1cb371bfd..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-pvc.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if not .Values.server.statefulSet.enabled -}} -{{- if .Values.server.persistentVolume.enabled -}} -{{- if not .Values.server.persistentVolume.existingClaim -}} -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - {{- if .Values.server.persistentVolume.annotations }} - annotations: -{{ toYaml .Values.server.persistentVolume.annotations | indent 4 }} - {{- end }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - name: {{ template "prometheus.server.fullname" . }} -spec: - accessModes: -{{ toYaml .Values.server.persistentVolume.accessModes | indent 4 }} -{{- if .Values.server.persistentVolume.storageClass }} -{{- if (eq "-" .Values.server.persistentVolume.storageClass) }} - storageClassName: "" -{{- else }} - storageClassName: "{{ .Values.server.persistentVolume.storageClass }}" -{{- end }} -{{- end }} -{{- if .Values.server.persistentVolume.volumeBindingMode }} - volumeBindingModeName: "{{ .Values.server.persistentVolume.volumeBindingMode }}" -{{- end }} - resources: - requests: - storage: "{{ .Values.server.persistentVolume.size }}" -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-service-headless.yaml b/infra/charts/feast/charts/prometheus/templates/server-service-headless.yaml deleted file mode 100644 index 3edc58c00f4..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-service-headless.yaml +++ /dev/null @@ -1,26 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if .Values.server.statefulSet.enabled -}} -apiVersion: v1 -kind: Service -metadata: -{{- if .Values.server.statefulSet.headless.annotations }} - annotations: -{{ toYaml .Values.server.statefulSet.headless.annotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} -{{- if .Values.server.statefulSet.headless.labels }} -{{ toYaml .Values.server.statefulSet.headless.labels | indent 4 }} -{{- end }} - name: {{ template "prometheus.server.fullname" . }}-headless -spec: - clusterIP: None - ports: - - name: http - port: {{ .Values.server.statefulSet.headless.servicePort }} - protocol: TCP - targetPort: 9090 - selector: - {{- include "prometheus.server.matchLabels" . | nindent 4 }} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-service.yaml b/infra/charts/feast/charts/prometheus/templates/server-service.yaml deleted file mode 100644 index 1f06151c038..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-service.yaml +++ /dev/null @@ -1,59 +0,0 @@ -{{- if .Values.server.enabled -}} -apiVersion: v1 -kind: Service -metadata: -{{- if .Values.server.service.annotations }} - annotations: -{{ toYaml .Values.server.service.annotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} -{{- if .Values.server.service.labels }} -{{ toYaml .Values.server.service.labels | indent 4 }} -{{- end }} - name: {{ template "prometheus.server.fullname" . }} -spec: -{{- if .Values.server.service.clusterIP }} - clusterIP: {{ .Values.server.service.clusterIP }} -{{- end }} -{{- if .Values.server.service.externalIPs }} - externalIPs: -{{ toYaml .Values.server.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.server.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.server.service.loadBalancerIP }} -{{- end }} -{{- if .Values.server.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.server.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} - ports: - - name: http - port: {{ .Values.server.service.servicePort }} - protocol: TCP - targetPort: 9090 - {{- if .Values.server.service.nodePort }} - nodePort: {{ .Values.server.service.nodePort }} - {{- end }} - {{- if .Values.server.service.gRPC.enabled }} - - name: grpc - port: {{ .Values.server.service.gRPC.servicePort }} - protocol: TCP - targetPort: 10901 - {{- if .Values.server.service.gRPC.nodePort }} - nodePort: {{ .Values.server.service.gRPC.nodePort }} - {{- end }} - {{- end }} - selector: - {{- if and .Values.server.statefulSet.enabled .Values.server.service.statefulsetReplica.enabled }} - statefulset.kubernetes.io/pod-name: {{ .Release.Name }}-{{ .Values.server.name }}-{{ .Values.server.service.statefulsetReplica.replica }} - {{- else -}} - {{- include "prometheus.server.matchLabels" . | nindent 4 }} -{{- if .Values.server.service.sessionAffinity }} - sessionAffinity: {{ .Values.server.service.sessionAffinity }} -{{- end }} - {{- end }} - type: "{{ .Values.server.service.type }}" -{{- end -}} diff --git a/infra/charts/feast/charts/prometheus/templates/server-serviceaccount.yaml b/infra/charts/feast/charts/prometheus/templates/server-serviceaccount.yaml deleted file mode 100644 index 68c64121aae..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-serviceaccount.yaml +++ /dev/null @@ -1,10 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if .Values.serviceAccounts.server.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - name: {{ template "prometheus.serviceAccountName.server" . }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-statefulset.yaml b/infra/charts/feast/charts/prometheus/templates/server-statefulset.yaml deleted file mode 100644 index ea6ae550f41..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-statefulset.yaml +++ /dev/null @@ -1,222 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if .Values.server.statefulSet.enabled -}} -apiVersion: apps/v1 -kind: StatefulSet -metadata: -{{- if .Values.server.statefulSet.annotations }} - annotations: -{{ toYaml .Values.server.statefulSet.annotations | indent 4 }} -{{- end }} - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - {{- if .Values.server.statefulSet.labels}} - {{ toYaml .Values.server.statefulSet.labels | nindent 4 }} - {{- end}} - name: {{ template "prometheus.server.fullname" . }} -spec: - serviceName: {{ template "prometheus.server.fullname" . }}-headless - selector: - matchLabels: - {{- include "prometheus.server.matchLabels" . | nindent 6 }} - replicas: {{ .Values.server.replicaCount }} - podManagementPolicy: {{ .Values.server.statefulSet.podManagementPolicy }} - template: - metadata: - {{- if .Values.server.podAnnotations }} - annotations: -{{ toYaml .Values.server.podAnnotations | indent 8 }} - {{- end }} - labels: - {{- include "prometheus.server.labels" . | nindent 8 }} - {{- if .Values.server.statefulSet.labels}} - {{ toYaml .Values.server.statefulSet.labels | nindent 8 }} - {{- end}} - spec: -{{- if .Values.server.affinity }} - affinity: -{{ toYaml .Values.server.affinity | indent 8 }} -{{- end }} -{{- if .Values.server.priorityClassName }} - priorityClassName: "{{ .Values.server.priorityClassName }}" -{{- end }} -{{- if .Values.server.schedulerName }} - schedulerName: "{{ .Values.server.schedulerName }}" -{{- end }} - serviceAccountName: {{ template "prometheus.serviceAccountName.server" . }} - containers: - {{- if .Values.configmapReload.prometheus.enabled }} - - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }}-{{ .Values.configmapReload.prometheus.name }} - image: "{{ .Values.configmapReload.prometheus.image.repository }}:{{ .Values.configmapReload.prometheus.image.tag }}" - imagePullPolicy: "{{ .Values.configmapReload.prometheus.image.pullPolicy }}" - args: - - --volume-dir=/etc/config - - --webhook-url=http://127.0.0.1:9090{{ .Values.server.prefixURL }}/-/reload - {{- range $key, $value := .Values.configmapReload.prometheus.extraArgs }} - - --{{ $key }}={{ $value }} - {{- end }} - {{- range .Values.configmapReload.prometheus.extraVolumeDirs }} - - --volume-dir={{ . }} - {{- end }} - resources: -{{ toYaml .Values.configmapReload.prometheus.resources | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/config - readOnly: true - {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} - - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- end }} - - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }} - image: "{{ .Values.server.image.repository }}:{{ .Values.server.image.tag }}" - imagePullPolicy: "{{ .Values.server.image.pullPolicy }}" - {{- if .Values.server.env }} - env: -{{ toYaml .Values.server.env | indent 12}} - {{- end }} - args: - {{- if .Values.server.retention }} - - --storage.tsdb.retention.time={{ .Values.server.retention }} - {{- end }} - - --config.file={{ .Values.server.configPath }} - - --storage.tsdb.path={{ .Values.server.persistentVolume.mountPath }} - - --web.console.libraries=/etc/prometheus/console_libraries - - --web.console.templates=/etc/prometheus/consoles - {{- range .Values.server.extraFlags }} - - --{{ . }} - {{- end }} - {{- range $key, $value := .Values.server.extraArgs }} - - --{{ $key }}={{ $value }} - {{- end }} - {{- if .Values.server.baseURL }} - - --web.external-url={{ .Values.server.baseURL }} - {{- end }} - ports: - - containerPort: 9090 - readinessProbe: - httpGet: - path: {{ .Values.server.prefixURL }}/-/ready - port: 9090 - initialDelaySeconds: {{ .Values.server.readinessProbeInitialDelay }} - timeoutSeconds: {{ .Values.server.readinessProbeTimeout }} - livenessProbe: - httpGet: - path: {{ .Values.server.prefixURL }}/-/healthy - port: 9090 - initialDelaySeconds: {{ .Values.server.livenessProbeInitialDelay }} - timeoutSeconds: {{ .Values.server.livenessProbeTimeout }} - resources: -{{ toYaml .Values.server.resources | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/config - - name: storage-volume - mountPath: {{ .Values.server.persistentVolume.mountPath }} - subPath: "{{ .Values.server.persistentVolume.subPath }}" - {{- range .Values.server.extraHostPathMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- range .Values.server.extraConfigmapMounts }} - - name: {{ $.Values.server.name }}-{{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- range .Values.server.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath }} - readOnly: {{ .readOnly }} - {{- end }} - {{- if .Values.server.extraVolumeMounts }} - {{ toYaml .Values.server.extraVolumeMounts | nindent 12 }} - {{- end }} - {{- if .Values.server.sidecarContainers }} - {{- toYaml .Values.server.sidecarContainers | nindent 8 }} - {{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: - {{ toYaml .Values.imagePullSecrets | indent 2 }} - {{- end }} - {{- if .Values.server.nodeSelector }} - nodeSelector: -{{ toYaml .Values.server.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.server.securityContext }} - securityContext: -{{ toYaml .Values.server.securityContext | indent 8 }} - {{- end }} - {{- if .Values.server.tolerations }} - tolerations: -{{ toYaml .Values.server.tolerations | indent 8 }} - {{- end }} - {{- if .Values.server.affinity }} - affinity: -{{ toYaml .Values.server.affinity | indent 8 }} - {{- end }} - terminationGracePeriodSeconds: {{ .Values.server.terminationGracePeriodSeconds }} - volumes: - - name: config-volume - configMap: - name: {{ if .Values.server.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.server.configMapOverrideName }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} - {{- range .Values.server.extraHostPathMounts }} - - name: {{ .name }} - hostPath: - path: {{ .hostPath }} - {{- end }} - {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} - - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} - configMap: - name: {{ .configMap }} - {{- end }} - {{- range .Values.server.extraConfigmapMounts }} - - name: {{ $.Values.server.name }}-{{ .name }} - configMap: - name: {{ .configMap }} - {{- end }} - {{- range .Values.server.extraSecretMounts }} - - name: {{ .name }} - secret: - secretName: {{ .secretName }} - {{- end }} - {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} - - name: {{ .name }} - configMap: - name: {{ .configMap }} - {{- end }} -{{- if .Values.server.extraVolumes }} -{{ toYaml .Values.server.extraVolumes | indent 8}} -{{- end }} -{{- if .Values.server.persistentVolume.enabled }} - volumeClaimTemplates: - - metadata: - name: storage-volume - {{- if .Values.server.persistentVolume.annotations }} - annotations: -{{ toYaml .Values.server.persistentVolume.annotations | indent 10 }} - {{- end }} - spec: - accessModes: -{{ toYaml .Values.server.persistentVolume.accessModes | indent 10 }} - resources: - requests: - storage: "{{ .Values.server.persistentVolume.size }}" - {{- if .Values.server.persistentVolume.storageClass }} - {{- if (eq "-" .Values.server.persistentVolume.storageClass) }} - storageClassName: "" - {{- else }} - storageClassName: "{{ .Values.server.persistentVolume.storageClass }}" - {{- end }} - {{- end }} -{{- else }} - - name: storage-volume - emptyDir: {} -{{- end }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/prometheus/templates/server-vpa.yaml b/infra/charts/feast/charts/prometheus/templates/server-vpa.yaml deleted file mode 100644 index ef3604eb0e0..00000000000 --- a/infra/charts/feast/charts/prometheus/templates/server-vpa.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.server.enabled -}} -{{- if .Values.server.verticalAutoscaler.enabled -}} -apiVersion: autoscaling.k8s.io/v1beta2 -kind: VerticalPodAutoscaler -metadata: - labels: - {{- include "prometheus.server.labels" . | nindent 4 }} - name: {{ template "prometheus.server.fullname" . }}-vpa -spec: - targetRef: -{{- if .Values.server.statefulSet.enabled }} - apiVersion: "apps/v1" - kind: StatefulSet -{{- else }} - apiVersion: "extensions/v1beta1" - kind: Deployment -{{- end }} - name: {{ template "prometheus.server.fullname" . }} - updatePolicy: - updateMode: {{ .Values.server.verticalAutoscaler.updateMode | default "Off" | quote }} - resourcePolicy: - containerPolicies: {{ .Values.server.verticalAutoscaler.containerPolicies | default list | toYaml | trim | nindent 4 }} -{{- end -}} {{/* if .Values.server.verticalAutoscaler.enabled */}} -{{- end -}} {{/* .Values.server.enabled */}} diff --git a/infra/charts/feast/charts/prometheus/values.yaml b/infra/charts/feast/charts/prometheus/values.yaml deleted file mode 100644 index d159a31d128..00000000000 --- a/infra/charts/feast/charts/prometheus/values.yaml +++ /dev/null @@ -1,1514 +0,0 @@ -rbac: - create: true - -podSecurityPolicy: - enabled: false - -imagePullSecrets: -# - name: "image-pull-secret" - -## Define serviceAccount names for components. Defaults to component's fully qualified name. -## -serviceAccounts: - alertmanager: - create: true - name: - nodeExporter: - create: true - name: - pushgateway: - create: true - name: - server: - create: true - name: - -alertmanager: - ## If false, alertmanager will not be installed - ## - enabled: false - - ## alertmanager container name - ## - name: alertmanager - - ## alertmanager container image - ## - image: - repository: prom/alertmanager - tag: v0.20.0 - pullPolicy: IfNotPresent - - ## alertmanager priorityClassName - ## - priorityClassName: "" - - ## Additional alertmanager container arguments - ## - extraArgs: {} - - ## The URL prefix at which the container can be accessed. Useful in the case the '-web.external-url' includes a slug - ## so that the various internal URLs are still able to access as they are in the default case. - ## (Optional) - prefixURL: "" - - ## External URL which can access alertmanager - baseURL: "http://localhost:9093" - - ## Additional alertmanager container environment variable - ## For instance to add a http_proxy - ## - extraEnv: {} - - ## Additional alertmanager Secret mounts - # Defines additional mounts with secrets. Secrets must be manually created in the namespace. - extraSecretMounts: [] - # - name: secret-files - # mountPath: /etc/secrets - # subPath: "" - # secretName: alertmanager-secret-files - # readOnly: true - - ## ConfigMap override where fullname is {{.Release.Name}}-{{.Values.alertmanager.configMapOverrideName}} - ## Defining configMapOverrideName will cause templates/alertmanager-configmap.yaml - ## to NOT generate a ConfigMap resource - ## - configMapOverrideName: "" - - ## The name of a secret in the same kubernetes namespace which contains the Alertmanager config - ## Defining configFromSecret will cause templates/alertmanager-configmap.yaml - ## to NOT generate a ConfigMap resource - ## - configFromSecret: "" - - ## The configuration file name to be loaded to alertmanager - ## Must match the key within configuration loaded from ConfigMap/Secret - ## - configFileName: alertmanager.yml - - ingress: - ## If true, alertmanager Ingress will be created - ## - enabled: false - - ## alertmanager Ingress annotations - ## - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: 'true' - - ## alertmanager Ingress additional labels - ## - extraLabels: {} - - ## alertmanager Ingress hostnames with optional path - ## Must be provided if Ingress is enabled - ## - hosts: [] - # - alertmanager.domain.com - # - domain.com/alertmanager - - ## 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 - - ## alertmanager Ingress TLS configuration - ## Secrets must be manually created in the namespace - ## - tls: [] - # - secretName: prometheus-alerts-tls - # hosts: - # - alertmanager.domain.com - - ## Alertmanager Deployment Strategy type - # strategy: - # type: Recreate - - ## Node tolerations for alertmanager scheduling to nodes with taints - ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - ## - tolerations: [] - # - key: "key" - # operator: "Equal|Exists" - # value: "value" - # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" - - ## Node labels for alertmanager pod assignment - ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ - ## - nodeSelector: {} - - ## Pod affinity - ## - affinity: {} - - ## PodDisruptionBudget settings - ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ - ## - podDisruptionBudget: - enabled: false - maxUnavailable: 1 - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - persistentVolume: - ## If true, alertmanager will create/use a Persistent Volume Claim - ## If false, use emptyDir - ## - enabled: true - - ## alertmanager data Persistent Volume access modes - ## Must match those of existing PV or dynamic provisioner - ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - accessModes: - - ReadWriteOnce - - ## alertmanager data Persistent Volume Claim annotations - ## - annotations: {} - - ## alertmanager data Persistent Volume existing claim name - ## Requires alertmanager.persistentVolume.enabled: true - ## If defined, PVC must be created manually before volume will be bound - existingClaim: "" - - ## alertmanager data Persistent Volume mount root path - ## - mountPath: /data - - ## alertmanager data Persistent Volume size - ## - size: 2Gi - - ## alertmanager data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - - ## alertmanager data Persistent Volume Binding Mode - ## If defined, volumeBindingMode: - ## If undefined (the default) or set to null, no volumeBindingMode spec is - ## set, choosing the default mode. - ## - # volumeBindingMode: "" - - ## Subdirectory of alertmanager data Persistent Volume to mount - ## Useful if the volume's root directory is not empty - ## - subPath: "" - - ## Annotations to be added to alertmanager pods - ## - podAnnotations: {} - ## Tell prometheus to use a specific set of alertmanager pods - ## instead of all alertmanager pods found in the same namespace - ## Useful if you deploy multiple releases within the same namespace - ## - ## prometheus.io/probe: alertmanager-teamA - - ## Labels to be added to Prometheus AlertManager pods - ## - podLabels: {} - - ## Specify if a Pod Security Policy for node-exporter 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' - - ## Use a StatefulSet if replicaCount needs to be greater than 1 (see below) - ## - replicaCount: 1 - - statefulSet: - ## If true, use a statefulset instead of a deployment for pod management. - ## This allows to scale replicas to more than 1 pod - ## - enabled: false - - podManagementPolicy: OrderedReady - - ## Alertmanager headless service to use for the statefulset - ## - headless: - annotations: {} - labels: {} - - ## Enabling peer mesh service end points for enabling the HA alert manager - ## Ref: https://github.com/prometheus/alertmanager/blob/master/README.md - # enableMeshPeer : true - - servicePort: 80 - - ## alertmanager resource requests and limits - ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: {} - # limits: - # cpu: 10m - # memory: 32Mi - # requests: - # cpu: 10m - # memory: 32Mi - - ## Security context to be added to alertmanager pods - ## - securityContext: - runAsUser: 65534 - runAsNonRoot: true - runAsGroup: 65534 - fsGroup: 65534 - - service: - annotations: {} - labels: {} - clusterIP: "" - - ## Enabling peer mesh service end points for enabling the HA alert manager - ## Ref: https://github.com/prometheus/alertmanager/blob/master/README.md - # enableMeshPeer : true - - ## List of IP addresses at which the alertmanager service is available - ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips - ## - externalIPs: [] - - loadBalancerIP: "" - loadBalancerSourceRanges: [] - servicePort: 80 - # nodePort: 30000 - sessionAffinity: None - type: ClusterIP - -## Monitors ConfigMap changes and POSTs to a URL -## Ref: https://github.com/jimmidyson/configmap-reload -## -configmapReload: - prometheus: - ## If false, the configmap-reload container will not be deployed - ## - enabled: true - - ## configmap-reload container name - ## - name: configmap-reload - - ## configmap-reload container image - ## - image: - repository: jimmidyson/configmap-reload - tag: v0.3.0 - pullPolicy: IfNotPresent - - ## Additional configmap-reload container arguments - ## - extraArgs: {} - ## Additional configmap-reload volume directories - ## - extraVolumeDirs: [] - - - ## Additional configmap-reload mounts - ## - extraConfigmapMounts: [] - # - name: prometheus-alerts - # mountPath: /etc/alerts.d - # subPath: "" - # configMap: prometheus-alerts - # readOnly: true - - - ## configmap-reload resource requests and limits - ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: {} - alertmanager: - ## If false, the configmap-reload container will not be deployed - ## - enabled: true - - ## configmap-reload container name - ## - name: configmap-reload - - ## configmap-reload container image - ## - image: - repository: jimmidyson/configmap-reload - tag: v0.3.0 - pullPolicy: IfNotPresent - - ## Additional configmap-reload container arguments - ## - extraArgs: {} - ## Additional configmap-reload volume directories - ## - extraVolumeDirs: [] - - - ## Additional configmap-reload mounts - ## - extraConfigmapMounts: [] - # - name: prometheus-alerts - # mountPath: /etc/alerts.d - # subPath: "" - # configMap: prometheus-alerts - # readOnly: true - - - ## configmap-reload resource requests and limits - ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: {} - -kubeStateMetrics: - ## If false, kube-state-metrics sub-chart will not be installed - ## Please see https://github.com/helm/charts/tree/master/stable/kube-state-metrics for configurable values - ## - enabled: true - -nodeExporter: - ## If false, node-exporter will not be installed - ## - enabled: false - - ## If true, node-exporter pods share the host network namespace - ## - hostNetwork: true - - ## If true, node-exporter pods share the host PID namespace - ## - hostPID: true - - ## node-exporter container name - ## - name: node-exporter - - ## node-exporter container image - ## - image: - repository: prom/node-exporter - tag: v0.18.1 - pullPolicy: IfNotPresent - - ## Specify if a Pod Security Policy for node-exporter 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' - - ## node-exporter priorityClassName - ## - priorityClassName: "" - - ## Custom Update Strategy - ## - updateStrategy: - type: RollingUpdate - - ## Additional node-exporter container arguments - ## - extraArgs: {} - - ## Additional node-exporter hostPath mounts - ## - extraHostPathMounts: [] - # - name: textfile-dir - # mountPath: /srv/txt_collector - # hostPath: /var/lib/node-exporter - # readOnly: true - # mountPropagation: HostToContainer - - extraConfigmapMounts: [] - # - name: certs-configmap - # mountPath: /prometheus - # configMap: certs-configmap - # readOnly: true - - ## Node tolerations for node-exporter scheduling to nodes with taints - ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - ## - tolerations: [] - # - key: "key" - # operator: "Equal|Exists" - # value: "value" - # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" - - ## Node labels for node-exporter pod assignment - ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ - ## - nodeSelector: {} - - ## Annotations to be added to node-exporter pods - ## - podAnnotations: {} - - ## Labels to be added to node-exporter pods - ## - pod: - labels: {} - - ## PodDisruptionBudget settings - ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ - ## - podDisruptionBudget: - enabled: false - maxUnavailable: 1 - - ## node-exporter resource limits & requests - ## Ref: https://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: {} - # limits: - # cpu: 200m - # memory: 50Mi - # requests: - # cpu: 100m - # memory: 30Mi - - ## Security context to be added to node-exporter pods - ## - securityContext: {} - # runAsUser: 0 - - service: - annotations: - prometheus.io/scrape: "true" - labels: {} - - # Exposed as a headless service: - # https://kubernetes.io/docs/concepts/services-networking/service/#headless-services - clusterIP: None - - ## List of IP addresses at which the node-exporter service is available - ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips - ## - externalIPs: [] - - hostPort: 9100 - loadBalancerIP: "" - loadBalancerSourceRanges: [] - servicePort: 9100 - type: ClusterIP - -server: - ## Prometheus server container name - ## - enabled: true - name: server - sidecarContainers: - - ## Prometheus server container image - ## - image: - repository: prom/prometheus - tag: v2.16.0 - pullPolicy: IfNotPresent - - ## prometheus server priorityClassName - ## - priorityClassName: "" - - ## The URL prefix at which the container can be accessed. Useful in the case the '-web.external-url' includes a slug - ## so that the various internal URLs are still able to access as they are in the default case. - ## (Optional) - prefixURL: "" - - ## External URL which can access alertmanager - ## Maybe same with Ingress host name - baseURL: "" - - ## Additional server container environment variables - ## - ## You specify this manually like you would a raw deployment manifest. - ## This means you can bind in environment variables from secrets. - ## - ## e.g. static environment variable: - ## - name: DEMO_GREETING - ## value: "Hello from the environment" - ## - ## e.g. secret environment variable: - ## - name: USERNAME - ## valueFrom: - ## secretKeyRef: - ## name: mysecret - ## key: username - env: [] - - extraFlags: - - web.enable-lifecycle - ## web.enable-admin-api flag controls access to the administrative HTTP API which includes functionality such as - ## deleting time series. This is disabled by default. - # - web.enable-admin-api - ## - ## storage.tsdb.no-lockfile flag controls BD locking - # - storage.tsdb.no-lockfile - ## - ## storage.tsdb.wal-compression flag enables compression of the write-ahead log (WAL) - # - storage.tsdb.wal-compression - - ## Path to a configuration file on prometheus server container FS - configPath: /etc/config/prometheus.yml - - global: - ## How frequently to scrape targets by default - ## - scrape_interval: 1m - ## How long until a scrape request times out - ## - scrape_timeout: 10s - ## How frequently to evaluate rules - ## - evaluation_interval: 1m - ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write - ## - remoteWrite: {} - ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_read - ## - remoteRead: {} - - ## Additional Prometheus server container arguments - ## - extraArgs: {} - - ## Additional InitContainers to initialize the pod - ## - extraInitContainers: [] - - ## Additional Prometheus server Volume mounts - ## - extraVolumeMounts: [] - - ## Additional Prometheus server Volumes - ## - extraVolumes: [] - - ## Additional Prometheus server hostPath mounts - ## - extraHostPathMounts: [] - # - name: certs-dir - # mountPath: /etc/kubernetes/certs - # subPath: "" - # hostPath: /etc/kubernetes/certs - # readOnly: true - - extraConfigmapMounts: [] - # - name: certs-configmap - # mountPath: /prometheus - # subPath: "" - # configMap: certs-configmap - # readOnly: true - - ## Additional Prometheus server Secret mounts - # Defines additional mounts with secrets. Secrets must be manually created in the namespace. - extraSecretMounts: [] - # - name: secret-files - # mountPath: /etc/secrets - # subPath: "" - # secretName: prom-secret-files - # readOnly: true - - ## ConfigMap override where fullname is {{.Release.Name}}-{{.Values.server.configMapOverrideName}} - ## Defining configMapOverrideName will cause templates/server-configmap.yaml - ## to NOT generate a ConfigMap resource - ## - configMapOverrideName: "" - - ingress: - ## If true, Prometheus server Ingress will be created - ## - enabled: false - - ## Prometheus server Ingress annotations - ## - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: 'true' - - ## Prometheus server Ingress additional labels - ## - extraLabels: {} - - ## Prometheus server Ingress hostnames with optional path - ## Must be provided if Ingress is enabled - ## - hosts: [] - # - prometheus.domain.com - # - domain.com/prometheus - - ## 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 - - ## Prometheus server Ingress TLS configuration - ## Secrets must be manually created in the namespace - ## - tls: [] - # - secretName: prometheus-server-tls - # hosts: - # - prometheus.domain.com - - ## Server Deployment Strategy type - # strategy: - # type: Recreate - - ## Node tolerations for server scheduling to nodes with taints - ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - ## - tolerations: [] - # - key: "key" - # operator: "Equal|Exists" - # value: "value" - # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" - - ## Node labels for Prometheus server pod assignment - ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ - ## - nodeSelector: {} - - ## Pod affinity - ## - affinity: {} - - ## PodDisruptionBudget settings - ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ - ## - podDisruptionBudget: - enabled: false - maxUnavailable: 1 - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - persistentVolume: - ## If true, Prometheus server will create/use a Persistent Volume Claim - ## If false, use emptyDir - ## - enabled: true - - ## Prometheus server data Persistent Volume access modes - ## Must match those of existing PV or dynamic provisioner - ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - accessModes: - - ReadWriteOnce - - ## Prometheus server data Persistent Volume annotations - ## - annotations: {} - - ## Prometheus server data Persistent Volume existing claim name - ## Requires server.persistentVolume.enabled: true - ## If defined, PVC must be created manually before volume will be bound - existingClaim: "" - - ## Prometheus server data Persistent Volume mount root path - ## - mountPath: /data - - ## Prometheus server data Persistent Volume size - ## - size: 8Gi - - ## Prometheus server data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - - ## Prometheus server data Persistent Volume Binding Mode - ## If defined, volumeBindingMode: - ## If undefined (the default) or set to null, no volumeBindingMode spec is - ## set, choosing the default mode. - ## - # volumeBindingMode: "" - - ## Subdirectory of Prometheus server data Persistent Volume to mount - ## Useful if the volume's root directory is not empty - ## - subPath: "" - - emptyDir: - sizeLimit: "" - - ## Annotations to be added to Prometheus server pods - ## - podAnnotations: {} - # iam.amazonaws.com/role: prometheus - - ## Labels to be added to Prometheus server pods - ## - podLabels: {} - - ## Prometheus AlertManager configuration - ## - alertmanagers: [] - - ## Specify if a Pod Security Policy for node-exporter 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' - - ## Use a StatefulSet if replicaCount needs to be greater than 1 (see below) - ## - replicaCount: 1 - - statefulSet: - ## If true, use a statefulset instead of a deployment for pod management. - ## This allows to scale replicas to more than 1 pod - ## - enabled: false - - annotations: {} - labels: {} - podManagementPolicy: OrderedReady - - ## Alertmanager headless service to use for the statefulset - ## - headless: - annotations: {} - labels: {} - servicePort: 80 - - ## Prometheus server readiness and liveness probe initial delay and timeout - ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ - ## - readinessProbeInitialDelay: 30 - readinessProbeTimeout: 30 - readinessProbeFailureThreshold: 3 - readinessProbeSuccessThreshold: 1 - livenessProbeInitialDelay: 30 - livenessProbeTimeout: 30 - livenessProbeFailureThreshold: 3 - livenessProbeSuccessThreshold: 1 - - ## Prometheus server resource requests and limits - ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: {} - # limits: - # cpu: 500m - # memory: 512Mi - # requests: - # cpu: 500m - # memory: 512Mi - - ## Vertical Pod Autoscaler config - ## Ref: https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler - verticalAutoscaler: - ## If true a VPA object will be created for the controller (either StatefulSet or Deployemnt, based on above configs) - enabled: false - # updateMode: "Auto" - # containerPolicies: - # - containerName: 'prometheus-server' - - ## Security context to be added to server pods - ## - securityContext: - runAsUser: 65534 - runAsNonRoot: true - runAsGroup: 65534 - fsGroup: 65534 - - service: - annotations: {} - labels: {} - clusterIP: "" - - ## List of IP addresses at which the Prometheus server service is available - ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips - ## - externalIPs: [] - - loadBalancerIP: "" - loadBalancerSourceRanges: [] - servicePort: 80 - sessionAffinity: None - type: ClusterIP - - ## Enable gRPC port on service to allow auto discovery with thanos-querier - gRPC: - enabled: false - servicePort: 10901 - # nodePort: 10901 - - ## If using a statefulSet (statefulSet.enabled=true), configure the - ## service to connect to a specific replica to have a consistent view - ## of the data. - statefulsetReplica: - enabled: false - replica: 0 - - ## Prometheus server pod termination grace period - ## - terminationGracePeriodSeconds: 300 - - ## Prometheus data retention period (default if not specified is 15 days) - ## - retention: "15d" - -pushgateway: - ## If false, pushgateway will not be installed - ## - enabled: false - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## pushgateway container name - ## - name: pushgateway - - ## pushgateway container image - ## - image: - repository: prom/pushgateway - tag: v1.0.1 - pullPolicy: IfNotPresent - - ## pushgateway priorityClassName - ## - priorityClassName: "" - - ## Additional pushgateway container arguments - ## - ## for example: persistence.file: /data/pushgateway.data - extraArgs: {} - - ingress: - ## If true, pushgateway Ingress will be created - ## - enabled: false - - ## pushgateway Ingress annotations - ## - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: 'true' - - ## pushgateway Ingress hostnames with optional path - ## Must be provided if Ingress is enabled - ## - hosts: [] - # - pushgateway.domain.com - # - domain.com/pushgateway - - ## 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 - - ## pushgateway Ingress TLS configuration - ## Secrets must be manually created in the namespace - ## - tls: [] - # - secretName: prometheus-alerts-tls - # hosts: - # - pushgateway.domain.com - - ## Node tolerations for pushgateway scheduling to nodes with taints - ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - ## - tolerations: [] - # - key: "key" - # operator: "Equal|Exists" - # value: "value" - # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" - - ## Node labels for pushgateway pod assignment - ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ - ## - nodeSelector: {} - - ## Annotations to be added to pushgateway pods - ## - podAnnotations: {} - - ## Specify if a Pod Security Policy for node-exporter 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' - - replicaCount: 1 - - ## PodDisruptionBudget settings - ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ - ## - podDisruptionBudget: - enabled: false - maxUnavailable: 1 - - ## pushgateway resource requests and limits - ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: {} - # limits: - # cpu: 10m - # memory: 32Mi - # requests: - # cpu: 10m - # memory: 32Mi - - ## Security context to be added to push-gateway pods - ## - securityContext: - runAsUser: 65534 - runAsNonRoot: true - - service: - annotations: - prometheus.io/probe: pushgateway - labels: {} - clusterIP: "" - - ## List of IP addresses at which the pushgateway service is available - ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips - ## - externalIPs: [] - - loadBalancerIP: "" - loadBalancerSourceRanges: [] - servicePort: 9091 - type: ClusterIP - - ## pushgateway Deployment Strategy type - # strategy: - # type: Recreate - - persistentVolume: - ## If true, pushgateway will create/use a Persistent Volume Claim - ## If false, use emptyDir - ## - enabled: false - - ## pushgateway data Persistent Volume access modes - ## Must match those of existing PV or dynamic provisioner - ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - accessModes: - - ReadWriteOnce - - ## pushgateway data Persistent Volume Claim annotations - ## - annotations: {} - - ## pushgateway data Persistent Volume existing claim name - ## Requires pushgateway.persistentVolume.enabled: true - ## If defined, PVC must be created manually before volume will be bound - existingClaim: "" - - ## pushgateway data Persistent Volume mount root path - ## - mountPath: /data - - ## pushgateway data Persistent Volume size - ## - size: 2Gi - - ## pushgateway data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - - ## pushgateway data Persistent Volume Binding Mode - ## If defined, volumeBindingMode: - ## If undefined (the default) or set to null, no volumeBindingMode spec is - ## set, choosing the default mode. - ## - # volumeBindingMode: "" - - ## Subdirectory of pushgateway data Persistent Volume to mount - ## Useful if the volume's root directory is not empty - ## - subPath: "" - - -## alertmanager ConfigMap entries -## -alertmanagerFiles: - alertmanager.yml: - global: {} - # slack_api_url: '' - - receivers: - - name: default-receiver - # slack_configs: - # - channel: '@you' - # send_resolved: true - - route: - group_wait: 10s - group_interval: 5m - receiver: default-receiver - repeat_interval: 3h - -## Prometheus server ConfigMap entries -## -serverFiles: - - ## Alerts configuration - ## Ref: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ - alerting_rules.yml: {} - # groups: - # - name: Instances - # rules: - # - alert: InstanceDown - # expr: up == 0 - # for: 5m - # labels: - # severity: page - # annotations: - # description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes.' - # summary: 'Instance {{ $labels.instance }} down' - ## DEPRECATED DEFAULT VALUE, unless explicitly naming your files, please use alerting_rules.yml - alerts: {} - - ## Records configuration - ## Ref: https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/ - recording_rules.yml: {} - ## DEPRECATED DEFAULT VALUE, unless explicitly naming your files, please use recording_rules.yml - rules: {} - - prometheus.yml: - rule_files: - - /etc/config/recording_rules.yml - - /etc/config/alerting_rules.yml - ## Below two files are DEPRECATED will be removed from this default values file - - /etc/config/rules - - /etc/config/alerts - - scrape_configs: - - job_name: prometheus - static_configs: - - targets: - - localhost:9090 - - # A scrape configuration for running Prometheus on a Kubernetes cluster. - # This uses separate scrape configs for cluster components (i.e. API server, node) - # and services to allow each to use different authentication configs. - # - # Kubernetes labels will be added as Prometheus labels on metrics via the - # `labelmap` relabeling action. - - # Scrape config for API servers. - # - # Kubernetes exposes API servers as endpoints to the default/kubernetes - # service so this uses `endpoints` role and uses relabelling to only keep - # the endpoints associated with the default/kubernetes service using the - # default named port `https`. This works for single API server deployments as - # well as HA API server deployments. - - job_name: 'kubernetes-apiservers' - - kubernetes_sd_configs: - - role: endpoints - - # Default to scraping over https. If required, just disable this or change to - # `http`. - scheme: https - - # This TLS & bearer token file config is used to connect to the actual scrape - # endpoints for cluster components. This is separate to discovery auth - # configuration because discovery & scraping are two separate concerns in - # Prometheus. The discovery auth config is automatic if Prometheus runs inside - # the cluster. Otherwise, more config options have to be provided within the - # . - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - # If your node certificates are self-signed or use a different CA to the - # master CA, then disable certificate verification below. Note that - # certificate verification is an integral part of a secure infrastructure - # so this should only be disabled in a controlled environment. You can - # disable certificate verification by uncommenting the line below. - # - insecure_skip_verify: true - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - - # Keep only the default/kubernetes service endpoints for the https port. This - # will add targets for each API server which Kubernetes adds an endpoint to - # the default/kubernetes service. - relabel_configs: - - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] - action: keep - regex: default;kubernetes;https - - - job_name: 'kubernetes-nodes' - - # Default to scraping over https. If required, just disable this or change to - # `http`. - scheme: https - - # This TLS & bearer token file config is used to connect to the actual scrape - # endpoints for cluster components. This is separate to discovery auth - # configuration because discovery & scraping are two separate concerns in - # Prometheus. The discovery auth config is automatic if Prometheus runs inside - # the cluster. Otherwise, more config options have to be provided within the - # . - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - # If your node certificates are self-signed or use a different CA to the - # master CA, then disable certificate verification below. Note that - # certificate verification is an integral part of a secure infrastructure - # so this should only be disabled in a controlled environment. You can - # disable certificate verification by uncommenting the line below. - # - insecure_skip_verify: true - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - - kubernetes_sd_configs: - - role: node - - relabel_configs: - - action: labelmap - regex: __meta_kubernetes_node_label_(.+) - - target_label: __address__ - replacement: kubernetes.default.svc:443 - - source_labels: [__meta_kubernetes_node_name] - regex: (.+) - target_label: __metrics_path__ - replacement: /api/v1/nodes/$1/proxy/metrics - - - - job_name: 'kubernetes-nodes-cadvisor' - - # Default to scraping over https. If required, just disable this or change to - # `http`. - scheme: https - - # This TLS & bearer token file config is used to connect to the actual scrape - # endpoints for cluster components. This is separate to discovery auth - # configuration because discovery & scraping are two separate concerns in - # Prometheus. The discovery auth config is automatic if Prometheus runs inside - # the cluster. Otherwise, more config options have to be provided within the - # . - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - # If your node certificates are self-signed or use a different CA to the - # master CA, then disable certificate verification below. Note that - # certificate verification is an integral part of a secure infrastructure - # so this should only be disabled in a controlled environment. You can - # disable certificate verification by uncommenting the line below. - # - insecure_skip_verify: true - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - - kubernetes_sd_configs: - - role: node - - # This configuration will work only on kubelet 1.7.3+ - # As the scrape endpoints for cAdvisor have changed - # if you are using older version you need to change the replacement to - # replacement: /api/v1/nodes/$1:4194/proxy/metrics - # more info here https://github.com/coreos/prometheus-operator/issues/633 - relabel_configs: - - action: labelmap - regex: __meta_kubernetes_node_label_(.+) - - target_label: __address__ - replacement: kubernetes.default.svc:443 - - source_labels: [__meta_kubernetes_node_name] - regex: (.+) - target_label: __metrics_path__ - replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor - - # Scrape config for service endpoints. - # - # The relabeling allows the actual service scrape endpoint to be configured - # via the following annotations: - # - # * `prometheus.io/scrape`: Only scrape services that have a value of `true` - # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need - # to set this to `https` & most likely set the `tls_config` of the scrape config. - # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. - # * `prometheus.io/port`: If the metrics are exposed on a different port to the - # service then set this appropriately. - - job_name: 'kubernetes-service-endpoints' - - kubernetes_sd_configs: - - role: endpoints - - relabel_configs: - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] - action: keep - regex: true - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] - action: replace - target_label: __scheme__ - regex: (https?) - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] - action: replace - target_label: __metrics_path__ - regex: (.+) - - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] - action: replace - target_label: __address__ - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 - - action: labelmap - regex: __meta_kubernetes_service_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - action: replace - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_service_name] - action: replace - target_label: kubernetes_name - - source_labels: [__meta_kubernetes_pod_node_name] - action: replace - target_label: kubernetes_node - - # Scrape config for slow service endpoints; same as above, but with a larger - # timeout and a larger interval - # - # The relabeling allows the actual service scrape endpoint to be configured - # via the following annotations: - # - # * `prometheus.io/scrape-slow`: Only scrape services that have a value of `true` - # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need - # to set this to `https` & most likely set the `tls_config` of the scrape config. - # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. - # * `prometheus.io/port`: If the metrics are exposed on a different port to the - # service then set this appropriately. - - job_name: 'kubernetes-service-endpoints-slow' - - scrape_interval: 5m - scrape_timeout: 30s - - kubernetes_sd_configs: - - role: endpoints - - relabel_configs: - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape_slow] - action: keep - regex: true - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] - action: replace - target_label: __scheme__ - regex: (https?) - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] - action: replace - target_label: __metrics_path__ - regex: (.+) - - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] - action: replace - target_label: __address__ - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 - - action: labelmap - regex: __meta_kubernetes_service_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - action: replace - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_service_name] - action: replace - target_label: kubernetes_name - - source_labels: [__meta_kubernetes_pod_node_name] - action: replace - target_label: kubernetes_node - - - job_name: 'prometheus-pushgateway' - honor_labels: true - - kubernetes_sd_configs: - - role: service - - relabel_configs: - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] - action: keep - regex: pushgateway - - # Example scrape config for probing services via the Blackbox Exporter. - # - # The relabeling allows the actual service scrape endpoint to be configured - # via the following annotations: - # - # * `prometheus.io/probe`: Only probe services that have a value of `true` - - job_name: 'kubernetes-services' - - metrics_path: /probe - params: - module: [http_2xx] - - kubernetes_sd_configs: - - role: service - - relabel_configs: - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] - action: keep - regex: true - - source_labels: [__address__] - target_label: __param_target - - target_label: __address__ - replacement: blackbox - - source_labels: [__param_target] - target_label: instance - - action: labelmap - regex: __meta_kubernetes_service_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_service_name] - target_label: kubernetes_name - - # Example scrape config for pods - # - # The relabeling allows the actual pod scrape endpoint to be configured via the - # following annotations: - # - # * `prometheus.io/scrape`: Only scrape pods that have a value of `true` - # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. - # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the default of `9102`. - - job_name: 'kubernetes-pods' - - kubernetes_sd_configs: - - role: pod - - relabel_configs: - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] - action: keep - regex: true - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] - action: replace - target_label: __metrics_path__ - regex: (.+) - - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] - action: replace - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 - target_label: __address__ - - action: labelmap - regex: __meta_kubernetes_pod_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - action: replace - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_pod_name] - action: replace - target_label: kubernetes_pod_name - - # Example Scrape config for pods which should be scraped slower. An useful example - # would be stackriver-exporter which querys an API on every scrape of the pod - # - # The relabeling allows the actual pod scrape endpoint to be configured via the - # following annotations: - # - # * `prometheus.io/scrape-slow`: Only scrape pods that have a value of `true` - # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. - # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the default of `9102`. - - job_name: 'kubernetes-pods-slow' - - scrape_interval: 5m - scrape_timeout: 30s - - kubernetes_sd_configs: - - role: pod - - relabel_configs: - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape_slow] - action: keep - regex: true - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] - action: replace - target_label: __metrics_path__ - regex: (.+) - - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] - action: replace - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 - target_label: __address__ - - action: labelmap - regex: __meta_kubernetes_pod_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - action: replace - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_pod_name] - action: replace - target_label: kubernetes_pod_name - -# adds additional scrape configs to prometheus.yml -# must be a string so you have to add a | after extraScrapeConfigs: -# example adds prometheus-blackbox-exporter scrape config -extraScrapeConfigs: - # - job_name: 'prometheus-blackbox-exporter' - # metrics_path: /probe - # params: - # module: [http_2xx] - # static_configs: - # - targets: - # - https://example.com - # relabel_configs: - # - source_labels: [__address__] - # target_label: __param_target - # - source_labels: [__param_target] - # target_label: instance - # - target_label: __address__ - # replacement: prometheus-blackbox-exporter:9115 - -# Adds option to add alert_relabel_configs to avoid duplicate alerts in alertmanager -# useful in H/A prometheus with different external labels but the same alerts -alertRelabelConfigs: - # alert_relabel_configs: - # - source_labels: [dc] - # regex: (.+)\d+ - # target_label: dc - -networkPolicy: - ## Enable creation of NetworkPolicy resources. - ## - enabled: false diff --git a/infra/charts/feast/charts/redis-10.5.6.tgz b/infra/charts/feast/charts/redis-10.5.6.tgz new file mode 100644 index 0000000000000000000000000000000000000000..f1e4ec4105584a91e7c091bc9ee9a39bd9dbb19e GIT binary patch literal 31002 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

c6w8`?kKK>~NP?u%J}6<#Iglv8X-ZWnn-J`R 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 literal 0 HcmV?d00001 diff --git a/infra/charts/feast/charts/redis/.helmignore b/infra/charts/feast/charts/redis/.helmignore deleted file mode 100644 index b2767ae17e9..00000000000 --- a/infra/charts/feast/charts/redis/.helmignore +++ /dev/null @@ -1,3 +0,0 @@ -.git -# OWNERS file for Kubernetes -OWNERS diff --git a/infra/charts/feast/charts/redis/Chart.yaml b/infra/charts/feast/charts/redis/Chart.yaml deleted file mode 100644 index 7f581f9a9be..00000000000 --- a/infra/charts/feast/charts/redis/Chart.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -name: redis -version: 10.5.6 -appVersion: 5.0.7 -description: Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. -keywords: -- redis -- keyvalue -- database -home: http://redis.io/ -icon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png -sources: -- https://github.com/bitnami/bitnami-docker-redis -maintainers: -- name: Bitnami - email: containers@bitnami.com -- name: desaintmartin - email: cedric@desaintmartin.fr -engine: gotpl diff --git a/infra/charts/feast/charts/redis/README.md b/infra/charts/feast/charts/redis/README.md deleted file mode 100644 index 72eb8364227..00000000000 --- a/infra/charts/feast/charts/redis/README.md +++ /dev/null @@ -1,497 +0,0 @@ - -# Redis - -[Redis](http://redis.io/) is an advanced key-value cache and store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs. - -## TL;DR; - -```bash -# Testing configuration -$ helm install my-release stable/redis -``` - -```bash -# Production configuration -$ helm install my-release stable/redis --values values-production.yaml -``` - -## Introduction - -This chart bootstraps a [Redis](https://github.com/bitnami/bitnami-docker-redis) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -Bitnami charts can be used with [Kubeapps](https://kubeapps.com/) for deployment and management of Helm Charts in clusters. This chart has been tested to work with NGINX Ingress, cert-manager, fluentd and Prometheus on top of the [BKPR](https://kubeprod.io/). - -## Prerequisites - -- Kubernetes 1.12+ -- Helm 2.11+ or Helm 3.0-beta3+ -- PV provisioner support in the underlying infrastructure - -## Installing the Chart - -To install the chart with the release name `my-release`: - -```bash -$ helm install my-release stable/redis -``` - -The command deploys Redis on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. - -> **Tip**: List all releases using `helm list` - -## Uninstalling the Chart - -To uninstall/delete the `my-release` deployment: - -```bash -$ helm delete my-release -``` - -The command removes all the Kubernetes components associated with the chart and deletes the release. - -## Parameters - -The following table lists the configurable parameters of the Redis chart and their default values. - -| Parameter | Description | Default | -| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | -| `global.imageRegistry` | Global Docker image registry | `nil` | -| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) | -| `global.storageClass` | Global storage class for dynamic provisioning | `nil` | -| `global.redis.password` | Redis password (overrides `password`) | `nil` | -| `image.registry` | Redis Image registry | `docker.io` | -| `image.repository` | Redis Image name | `bitnami/redis` | -| `image.tag` | Redis Image tag | `{TAG_NAME}` | -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `image.pullSecrets` | Specify docker-registry secret names as an array | `nil` | -| `nameOverride` | String to partially override redis.fullname template with a string (will prepend the release name) | `nil` | -| `fullnameOverride` | String to fully override redis.fullname template with a string | `nil` | -| `cluster.enabled` | Use master-slave topology | `true` | -| `cluster.slaveCount` | Number of slaves | `1` | -| `existingSecret` | Name of existing secret object (for password authentication) | `nil` | -| `existingSecretPasswordKey` | Name of key containing password to be retrieved from the existing secret | `nil` | -| `usePassword` | Use password | `true` | -| `usePasswordFile` | Mount passwords as files instead of environment variables | `false` | -| `password` | Redis password (ignored if existingSecret set) | Randomly generated | -| `configmap` | Additional common Redis node configuration (this value is evaluated as a template) | See values.yaml | -| `clusterDomain` | Kubernetes DNS Domain name to use | `cluster.local` | -| `networkPolicy.enabled` | Enable NetworkPolicy | `false` | -| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | -| `networkPolicy.ingressNSMatchLabels` | Allow connections from other namespaces | `{}` | -| `networkPolicy.ingressNSPodMatchLabels` | For other namespaces match by pod labels and namespace labels | `{}` | -| `securityContext.enabled` | Enable security context (both redis master and slave pods) | `true` | -| `securityContext.fsGroup` | Group ID for the container (both redis master and slave pods) | `1001` | -| `securityContext.runAsUser` | User ID for the container (both redis master and slave pods) | `1001` | -| `securityContext.sysctls` | Set namespaced sysctls for the container (both redis master and slave pods) | `nil` | -| `serviceAccount.create` | Specifies whether a ServiceAccount should be created | `false` | -| `serviceAccount.name` | The name of the ServiceAccount to create | Generated using the fullname template | -| `rbac.create` | Specifies whether RBAC resources should be created | `false` | -| `rbac.role.rules` | Rules to create | `[]` | -| `metrics.enabled` | Start a side-car prometheus exporter | `false` | -| `metrics.image.registry` | Redis exporter image registry | `docker.io` | -| `metrics.image.repository` | Redis exporter image name | `bitnami/redis-exporter` | -| `metrics.image.tag` | Redis exporter image tag | `{TAG_NAME}` | -| `metrics.image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `nil` | -| `metrics.extraArgs` | Extra arguments for the binary; possible values [here](https://github.com/oliver006/redis_exporter#flags) | {} | -| `metrics.podLabels` | Additional labels for Metrics exporter pod | {} | -| `metrics.podAnnotations` | Additional annotations for Metrics exporter pod | {} | -| `metrics.resources` | Exporter resource requests/limit | Memory: `256Mi`, CPU: `100m` | -| `metrics.serviceMonitor.enabled` | if `true`, creates a Prometheus Operator ServiceMonitor (also requires `metrics.enabled` to be `true`) | `false` | -| `metrics.serviceMonitor.namespace` | Optional namespace which Prometheus is running in | `nil` | -| `metrics.serviceMonitor.interval` | How frequently to scrape metrics (use by default, falling back to Prometheus' default) | `nil` | -| `metrics.serviceMonitor.selector` | Default to kube-prometheus install (CoreOS recommended), but should be set according to Prometheus install | `{ prometheus: kube-prometheus }` | -| `metrics.service.type` | Kubernetes Service type (redis metrics) | `ClusterIP` | -| `metrics.service.annotations` | Annotations for the services to monitor (redis master and redis slave service) | {} | -| `metrics.service.labels` | Additional labels for the metrics service | {} | -| `metrics.service.loadBalancerIP` | loadBalancerIP if redis metrics service type is `LoadBalancer` | `nil` | -| `metrics.priorityClassName` | Metrics exporter pod priorityClassName | {} | -| `metrics.prometheusRule.enabled` | Set this to true to create prometheusRules for Prometheus operator | `false` | -| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so prometheusRules will be discovered by Prometheus | `{}` | -| `metrics.prometheusRule.namespace` | namespace where prometheusRules resource should be created | Same namespace as redis | -| `metrics.prometheusRule.rules` | [rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) to be created, check values for an example. | `[]` | -| `persistence.existingClaim` | Provide an existing PersistentVolumeClaim | `nil` | -| `master.persistence.enabled` | Use a PVC to persist data (master node) | `true` | -| `master.persistence.path` | Path to mount the volume at, to use other images | `/data` | -| `master.persistence.subPath` | Subdirectory of the volume to mount at | `""` | -| `master.persistence.storageClass` | Storage class of backing PVC | `generic` | -| `master.persistence.accessModes` | Persistent Volume Access Modes | `[ReadWriteOnce]` | -| `master.persistence.size` | Size of data volume | `8Gi` | -| `master.persistence.matchLabels` | matchLabels persistent volume selector | `{}` | -| `master.persistence.matchExpressions` | matchExpressions persistent volume selector | `{}` | -| `master.statefulset.updateStrategy` | Update strategy for StatefulSet | onDelete | -| `master.statefulset.rollingUpdatePartition` | Partition update strategy | `nil` | -| `master.podLabels` | Additional labels for Redis master pod | {} | -| `master.podAnnotations` | Additional annotations for Redis master pod | {} | -| `redisPort` | Redis port (in both master and slaves) | `6379` | -| `master.command` | Redis master entrypoint string. The command `redis-server` is executed if this is not provided. | `/run.sh` | -| `master.configmap` | Additional Redis configuration for the master nodes (this value is evaluated as a template) | `nil` | -| `master.disableCommands` | Array of Redis commands to disable (master) | `["FLUSHDB", "FLUSHALL"]` | -| `master.extraFlags` | Redis master additional command line flags | [] | -| `master.nodeSelector` | Redis master Node labels for pod assignment | {"beta.kubernetes.io/arch": "amd64"} | -| `master.tolerations` | Toleration labels for Redis master pod assignment | [] | -| `master.affinity` | Affinity settings for Redis master pod assignment | {} | -| `master.schedulerName` | Name of an alternate scheduler | `nil` | -| `master.service.type` | Kubernetes Service type (redis master) | `ClusterIP` | -| `master.service.port` | Kubernetes Service port (redis master) | `6379` | -| `master.service.nodePort` | Kubernetes Service nodePort (redis master) | `nil` | -| `master.service.annotations` | annotations for redis master service | {} | -| `master.service.labels` | Additional labels for redis master service | {} | -| `master.service.loadBalancerIP` | loadBalancerIP if redis master service type is `LoadBalancer` | `nil` | -| `master.service.loadBalancerSourceRanges` | loadBalancerSourceRanges if redis master service type is `LoadBalancer` | `nil` | -| `master.resources` | Redis master CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | -| `master.livenessProbe.enabled` | Turn on and off liveness probe (redis master pod) | `true` | -| `master.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (redis master pod) | `30` | -| `master.livenessProbe.periodSeconds` | How often to perform the probe (redis master pod) | `30` | -| `master.livenessProbe.timeoutSeconds` | When the probe times out (redis master pod) | `5` | -| `master.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis master pod) | `1` | -| `master.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | -| `master.readinessProbe.enabled` | Turn on and off readiness probe (redis master pod) | `true` | -| `master.readinessProbe.initialDelaySeconds` | Delay before readiness probe is initiated (redis master pod) | `5` | -| `master.readinessProbe.periodSeconds` | How often to perform the probe (redis master pod) | `10` | -| `master.readinessProbe.timeoutSeconds` | When the probe times out (redis master pod) | `1` | -| `master.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis master pod) | `1` | -| `master.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | -| `master.priorityClassName` | Redis Master pod priorityClassName | {} | -| `volumePermissions.enabled` | Enable init container that changes volume permissions in the registry (for cases where the default k8s `runAsUser` and `fsUser` values do not work) | `false` | -| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | -| `volumePermissions.image.repository` | Init container volume-permissions image name | `bitnami/minideb` | -| `volumePermissions.image.tag` | Init container volume-permissions image tag | `buster` | -| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `Always` | -| `volumePermissions.resources ` | Init container volume-permissions CPU/Memory resource requests/limits | {} | -| `slave.service.type` | Kubernetes Service type (redis slave) | `ClusterIP` | -| `slave.service.nodePort` | Kubernetes Service nodePort (redis slave) | `nil` | -| `slave.service.annotations` | annotations for redis slave service | {} | -| `slave.service.labels` | Additional labels for redis slave service | {} | -| `slave.service.port` | Kubernetes Service port (redis slave) | `6379` | -| `slave.service.loadBalancerIP` | LoadBalancerIP if Redis slave service type is `LoadBalancer` | `nil` | -| `slave.service.loadBalancerSourceRanges` | loadBalancerSourceRanges if Redis slave service type is `LoadBalancer` | `nil` | -| `slave.command` | Redis slave entrypoint array. The docker image's ENTRYPOINT is used if this is not provided. | `/run.sh` | -| `slave.configmap` | Additional Redis configuration for the slave nodes (this value is evaluated as a template) | `nil` | -| `slave.disableCommands` | Array of Redis commands to disable (slave) | `[FLUSHDB, FLUSHALL]` | -| `slave.extraFlags` | Redis slave additional command line flags | `[]` | -| `slave.livenessProbe.enabled` | Turn on and off liveness probe (redis slave pod) | `true` | -| `slave.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (redis slave pod) | `30` | -| `slave.livenessProbe.periodSeconds` | How often to perform the probe (redis slave pod) | `10` | -| `slave.livenessProbe.timeoutSeconds` | When the probe times out (redis slave pod) | `5` | -| `slave.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis slave pod) | `1` | -| `slave.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | -| `slave.readinessProbe.enabled` | Turn on and off slave.readiness probe (redis slave pod) | `true` | -| `slave.readinessProbe.initialDelaySeconds` | Delay before slave.readiness probe is initiated (redis slave pod) | `5` | -| `slave.readinessProbe.periodSeconds` | How often to perform the probe (redis slave pod) | `10` | -| `slave.readinessProbe.timeoutSeconds` | When the probe times out (redis slave pod) | `10` | -| `slave.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis slave pod) | `1` | -| `slave.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. (redis slave pod) | `5` | -| `slave.persistence.enabled` | Use a PVC to persist data (slave node) | `true` | -| `slave.persistence.path` | Path to mount the volume at, to use other images | `/data` | -| `slave.persistence.subPath` | Subdirectory of the volume to mount at | `""` | -| `slave.persistence.storageClass` | Storage class of backing PVC | `generic` | -| `slave.persistence.accessModes` | Persistent Volume Access Modes | `[ReadWriteOnce]` | -| `slave.persistence.size` | Size of data volume | `8Gi` | -| `slave.persistence.matchLabels` | matchLabels persistent volume selector | `{}` | -| `slave.persistence.matchExpressions` | matchExpressions persistent volume selector | `{}` | -| `slave.statefulset.updateStrategy` | Update strategy for StatefulSet | onDelete | -| `slave.statefulset.rollingUpdatePartition` | Partition update strategy | `nil` | -| `slave.podLabels` | Additional labels for Redis slave pod | `master.podLabels` | -| `slave.podAnnotations` | Additional annotations for Redis slave pod | `master.podAnnotations` | -| `slave.schedulerName` | Name of an alternate scheduler | `nil` | -| `slave.resources` | Redis slave CPU/Memory resource requests/limits | `{}` | -| `slave.affinity` | Enable node/pod affinity for slaves | {} | -| `slave.priorityClassName` | Redis Slave pod priorityClassName | {} | -| `sentinel.enabled` | Enable sentinel containers | `false` | -| `sentinel.usePassword` | Use password for sentinel containers | `true` | -| `sentinel.masterSet` | Name of the sentinel master set | `mymaster` | -| `sentinel.initialCheckTimeout` | Timeout for querying the redis sentinel service for the active sentinel list | `5` | -| `sentinel.quorum` | Quorum for electing a new master | `2` | -| `sentinel.downAfterMilliseconds` | Timeout for detecting a Redis node is down | `60000` | -| `sentinel.failoverTimeout` | Timeout for performing a election failover | `18000` | -| `sentinel.parallelSyncs` | Number of parallel syncs in the cluster | `1` | -| `sentinel.port` | Redis Sentinel port | `26379` | -| `sentinel.configmap` | Additional Redis configuration for the sentinel nodes (this value is evaluated as a template) | `nil` | -| `sentinel.staticID` | Enable static IDs for sentinel replicas (If disabled IDs will be randomly generated on startup) | `false` | -| `sentinel.service.type` | Kubernetes Service type (redis sentinel) | `ClusterIP` | -| `sentinel.service.nodePort` | Kubernetes Service nodePort (redis sentinel) | `nil` | -| `sentinel.service.annotations` | annotations for redis sentinel service | {} | -| `sentinel.service.labels` | Additional labels for redis sentinel service | {} | -| `sentinel.service.redisPort` | Kubernetes Service port for Redis read only operations | `6379` | -| `sentinel.service.sentinelPort` | Kubernetes Service port for Redis sentinel | `26379` | -| `sentinel.service.redisNodePort` | Kubernetes Service node port for Redis read only operations | `` | -| `sentinel.service.sentinelNodePort` | Kubernetes Service node port for Redis sentinel | `` | -| `sentinel.service.loadBalancerIP` | LoadBalancerIP if Redis sentinel service type is `LoadBalancer` | `nil` | -| `sentinel.livenessProbe.enabled` | Turn on and off liveness probe (redis sentinel pod) | `true` | -| `sentinel.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (redis sentinel pod) | `5` | -| `sentinel.livenessProbe.periodSeconds` | How often to perform the probe (redis sentinel container) | `5` | -| `sentinel.livenessProbe.timeoutSeconds` | When the probe times out (redis sentinel container) | `5` | -| `sentinel.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis sentinel container) | `1` | -| `sentinel.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | -| `sentinel.readinessProbe.enabled` | Turn on and off sentinel.readiness probe (redis sentinel pod) | `true` | -| `sentinel.readinessProbe.initialDelaySeconds` | Delay before sentinel.readiness probe is initiated (redis sentinel pod) | `5` | -| `sentinel.readinessProbe.periodSeconds` | How often to perform the probe (redis sentinel pod) | `5` | -| `sentinel.readinessProbe.timeoutSeconds` | When the probe times out (redis sentinel container) | `1` | -| `sentinel.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis sentinel container) | `1` | -| `sentinel.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. (redis sentinel container) | `5` | -| `sentinel.resources` | Redis sentinel CPU/Memory resource requests/limits | `{}` | -| `sentinel.image.registry` | Redis Sentinel Image registry | `docker.io` | -| `sentinel.image.repository` | Redis Sentinel Image name | `bitnami/redis-sentinel` | -| `sentinel.image.tag` | Redis Sentinel Image tag | `{TAG_NAME}` | -| `sentinel.image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `sentinel.image.pullSecrets` | Specify docker-registry secret names as an array | `nil` | -| `sysctlImage.enabled` | Enable an init container to modify Kernel settings | `false` | -| `sysctlImage.command` | sysctlImage command to execute | [] | -| `sysctlImage.registry` | sysctlImage Init container registry | `docker.io` | -| `sysctlImage.repository` | sysctlImage Init container name | `bitnami/minideb` | -| `sysctlImage.tag` | sysctlImage Init container tag | `buster` | -| `sysctlImage.pullPolicy` | sysctlImage Init container pull policy | `Always` | -| `sysctlImage.mountHostSys` | Mount the host `/sys` folder to `/host-sys` | `false` | -| `sysctlImage.resources` | sysctlImage Init container CPU/Memory resource requests/limits | {} | -| `podSecurityPolicy.create` | Specifies whether a PodSecurityPolicy should be created | `false` | - -Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, - -```bash -$ helm install my-release \ - --set password=secretpassword \ - stable/redis -``` - -The above command sets the Redis server password to `secretpassword`. - -Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, - -```bash -$ helm install my-release -f values.yaml stable/redis -``` - -> **Tip**: You can use the default [values.yaml](values.yaml) - -> **Note for minikube users**: Current versions of minikube (v0.24.1 at the time of writing) provision `hostPath` persistent volumes that are only writable by root. Using chart defaults cause pod failure for the Redis pod as it attempts to write to the `/bitnami` directory. Consider installing Redis with `--set persistence.enabled=false`. See minikube issue [1990](https://github.com/kubernetes/minikube/issues/1990) for more information. - -## Configuration and installation details - -### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) - -It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. - -Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. - -### Production configuration - -This chart includes a `values-production.yaml` file where you can find some parameters oriented to production configuration in comparison to the regular `values.yaml`. You can use this file instead of the default one. - -- Number of slaves: -```diff -- cluster.slaveCount: 2 -+ cluster.slaveCount: 3 -``` - -- Enable NetworkPolicy: -```diff -- networkPolicy.enabled: false -+ networkPolicy.enabled: true -``` - -- Start a side-car prometheus exporter: -```diff -- metrics.enabled: false -+ metrics.enabled: true -``` - -### Cluster topologies - -#### Default: Master-Slave - -When installing the chart with `cluster.enabled=true`, it will deploy a Redis master StatefulSet (only one master node allowed) and a Redis slave StatefulSet. The slaves will be read-replicas of the master. Two services will be exposed: - - - Redis Master service: Points to the master, where read-write operations can be performed - - Redis Slave service: Points to the slaves, where only read operations are allowed. - -In case the master crashes, the slaves will wait until the master node is respawned again by the Kubernetes Controller Manager. - -#### Master-Slave with Sentinel - -When installing the chart with `cluster.enabled=true` and `sentinel.enabled=true`, it will deploy a Redis master StatefulSet (only one master allowed) and a Redis slave StatefulSet. In this case, the pods will contain en extra container with Redis Sentinel. This container will form a cluster of Redis Sentinel nodes, which will promote a new master in case the actual one fails. In addition to this, only one service is exposed: - - - Redis service: Exposes port 6379 for Redis read-only operations and port 26379 for accesing Redis Sentinel. - -For read-only operations, access the service using port 6379. For write operations, it's necessary to access the Redis Sentinel cluster and query the current master using the command below (using redis-cli or similar: - -``` -SENTINEL get-master-addr-by-name -``` -This command will return the address of the current master, which can be accessed from inside the cluster. - -In case the current master crashes, the Sentinel containers will elect a new master node. - -### Using password file -To use a password file for Redis you need to create a secret containing the password. - -> *NOTE*: It is important that the file with the password must be called `redis-password` - -And then deploy the Helm Chart using the secret name as parameter: - -```console -usePassword=true -usePasswordFile=true -existingSecret=redis-password-file -sentinels.enabled=true -metrics.enabled=true -``` - -### Metrics - -The chart optionally can start a metrics exporter for [prometheus](https://prometheus.io). The metrics endpoint (port 9121) is exposed in the service. Metrics can be scraped from within the cluster using something similar as the described in the [example Prometheus scrape configuration](https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml). If metrics are to be scraped from outside the cluster, the Kubernetes API proxy can be utilized to access the endpoint. - -### Host Kernel Settings -Redis may require some changes in the kernel of the host machine to work as expected, in particular increasing the `somaxconn` value and disabling transparent huge pages. -To do so, you can set up a privileged initContainer with the `sysctlImage` config values, for example: -``` -sysctlImage: - enabled: true - mountHostSys: true - command: - - /bin/sh - - -c - - |- - install_packages procps - sysctl -w net.core.somaxconn=10000 - echo never > /host-sys/kernel/mm/transparent_hugepage/enabled -``` - -Alternatively, for Kubernetes 1.12+ you can set `securityContext.sysctls` which will configure sysctls for master and slave pods. Example: - -```yaml -securityContext: - sysctls: - - name: net.core.somaxconn - value: "10000" -``` - -Note that this will not disable transparent huge tables. - -## Persistence - -By default, the chart mounts a [Persistent Volume](http://kubernetes.io/docs/user-guide/persistent-volumes/) at the `/data` path. The volume is created using dynamic volume provisioning. If a Persistent Volume Claim already exists, specify it during installation. - -### Existing PersistentVolumeClaim - -1. Create the PersistentVolume -2. Create the PersistentVolumeClaim -3. Install the chart - -```bash -$ helm install my-release --set persistence.existingClaim=PVC_NAME stable/redis -``` - -## NetworkPolicy - -To enable network policy for Redis, install -[a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), -and set `networkPolicy.enabled` to `true`. - -For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting -the DefaultDeny namespace annotation. Note: this will enforce policy for _all_ pods in the namespace: - - kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" - -With NetworkPolicy enabled, only pods with the generated client label will be -able to connect to Redis. This label will be displayed in the output -after a successful install. - -With `networkPolicy.ingressNSMatchLabels` pods from other namespaces can connect to redis. Set `networkPolicy.ingressNSPodMatchLabels` to match pod labels in matched namespace. For example, for a namespace labeled `redis=external` and pods in that namespace labeled `redis-client=true` the fields should be set: - -``` -networkPolicy: - enabled: true - ingressNSMatchLabels: - redis: external - ingressNSPodMatchLabels: - redis-client: true -``` - -## 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 10.0.0 - -For releases with `usePassword: true`, the value `sentinel.usePassword` controls whether the password authentication also applies to the sentinel port. This defaults to `true` for a secure configuration, however it is possible to disable to account for the following cases: -* Using a version of redis-sentinel prior to `5.0.1` where the authentication feature was introduced. -* Where redis clients need to be updated to support sentinel authentication. - -If using a master/slave topology, or with `usePassword: false`, no action is required. - -### To 8.0.18 - -For releases with `metrics.enabled: true` the default tag for the exporter image is now `v1.x.x`. This introduces many changes including metrics names. You'll want to use [this dashboard](https://github.com/oliver006/redis_exporter/blob/master/contrib/grafana_prometheus_redis_dashboard.json) now. Please see the [redis_exporter github page](https://github.com/oliver006/redis_exporter#upgrading-from-0x-to-1x) for more details. - -### To 7.0.0 - -This version causes a change in the Redis Master StatefulSet definition, so the command helm upgrade would not work out of the box. As an alternative, one of the following could be done: - - - Recommended: Create a clone of the Redis Master PVC (for example, using projects like [this one](https://github.com/edseymour/pvc-transfer)). Then launch a fresh release reusing this cloned PVC. - - ``` - helm install my-release stable/redis --set persistence.existingClaim= - ``` - - - Alternative (not recommended, do at your own risk): `helm delete --purge` does not remove the PVC assigned to the Redis Master StatefulSet. As a consequence, the following commands can be done to upgrade the release - - ``` - helm delete --purge - helm install stable/redis - ``` - -Previous versions of the chart were not using persistence in the slaves, so this upgrade would add it to them. Another important change is that no values are inherited from master to slaves. For example, in 6.0.0 `slaves.readinessProbe.periodSeconds`, if empty, would be set to `master.readinessProbe.periodSeconds`. This approach lacked transparency and was difficult to maintain. From now on, all the slave parameters must be configured just as it is done with the masters. - -Some values have changed as well: - - - `master.port` and `slave.port` have been changed to `redisPort` (same value for both master and slaves) - - `master.securityContext` and `slave.securityContext` have been changed to `securityContext`(same values for both master and slaves) - -By default, the upgrade will not change the cluster topology. In case you want to use Redis Sentinel, you must explicitly set `sentinel.enabled` to `true`. - -### To 6.0.0 - -Previous versions of the chart were using an init-container to change the permissions of the volumes. This was done in case the `securityContext` directive in the template was not enough for that (for example, with cephFS). In this new version of the chart, this container is disabled by default (which should not affect most of the deployments). If your installation still requires that init container, execute `helm upgrade` with the `--set volumePermissions.enabled=true`. - -### To 5.0.0 - -The default image in this release may be switched out for any image containing the `redis-server` -and `redis-cli` binaries. If `redis-server` is not the default image ENTRYPOINT, `master.command` -must be specified. - -#### Breaking changes -- `master.args` and `slave.args` are removed. Use `master.command` or `slave.command` instead in order to override the image entrypoint, or `master.extraFlags` to pass additional flags to `redis-server`. -- `disableCommands` is now interpreted as an array of strings instead of a string of comma separated values. -- `master.persistence.path` now defaults to `/data`. - -### 4.0.0 - -This version removes the `chart` label from the `spec.selector.matchLabels` -which is immutable since `StatefulSet apps/v1beta2`. It has been inadvertently -added, causing any subsequent upgrade to fail. See https://github.com/helm/charts/issues/7726. - -It also fixes https://github.com/helm/charts/issues/7726 where a deployment `extensions/v1beta1` can not be upgraded if `spec.selector` is not explicitly set. - -Finally, it fixes https://github.com/helm/charts/issues/7803 by removing mutable labels in `spec.VolumeClaimTemplate.metadata.labels` so that it is upgradable. - -In order to upgrade, delete the Redis StatefulSet before upgrading: -```bash -$ kubectl delete statefulsets.apps --cascade=false my-release-redis-master -``` -And edit the Redis slave (and metrics if enabled) deployment: -```bash -kubectl patch deployments my-release-redis-slave --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]' -kubectl patch deployments my-release-redis-metrics --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]' -``` - -## Notable changes - -### 9.0.0 -The metrics exporter has been changed from a separate deployment to a sidecar container, due to the latest changes in the Redis exporter code. Check the [official page](https://github.com/oliver006/redis_exporter/) for more information. The metrics container image was changed from oliver006/redis_exporter to bitnami/redis-exporter (Bitnami's maintained package of oliver006/redis_exporter). - -### 7.0.0 -In order to improve the performance in case of slave failure, we added persistence to the read-only slaves. That means that we moved from Deployment to StatefulSets. This should not affect upgrades from previous versions of the chart, as the deployments did not contain any persistence at all. - -This version also allows enabling Redis Sentinel containers inside of the Redis Pods (feature disabled by default). In case the master crashes, a new Redis node will be elected as master. In order to query the current master (no redis master service is exposed), you need to query first the Sentinel cluster. Find more information [in this section](#master-slave-with-sentinel). diff --git a/infra/charts/feast/charts/redis/ci/default-values.yaml b/infra/charts/feast/charts/redis/ci/default-values.yaml deleted file mode 100644 index fc2ba605ada..00000000000 --- a/infra/charts/feast/charts/redis/ci/default-values.yaml +++ /dev/null @@ -1 +0,0 @@ -# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/infra/charts/feast/charts/redis/ci/dev-values.yaml b/infra/charts/feast/charts/redis/ci/dev-values.yaml deleted file mode 100644 index be01913b5b5..00000000000 --- a/infra/charts/feast/charts/redis/ci/dev-values.yaml +++ /dev/null @@ -1,9 +0,0 @@ -master: - persistence: - enabled: false - -cluster: - enabled: true - slaveCount: 1 - -usePassword: false diff --git a/infra/charts/feast/charts/redis/ci/extra-flags-values.yaml b/infra/charts/feast/charts/redis/ci/extra-flags-values.yaml deleted file mode 100644 index 71132f76e19..00000000000 --- a/infra/charts/feast/charts/redis/ci/extra-flags-values.yaml +++ /dev/null @@ -1,11 +0,0 @@ -master: - extraFlags: - - --maxmemory-policy allkeys-lru - persistence: - enabled: false -slave: - extraFlags: - - --maxmemory-policy allkeys-lru - persistence: - enabled: false -usePassword: false diff --git a/infra/charts/feast/charts/redis/ci/insecure-sentinel-values.yaml b/infra/charts/feast/charts/redis/ci/insecure-sentinel-values.yaml deleted file mode 100644 index 2e9174f4954..00000000000 --- a/infra/charts/feast/charts/redis/ci/insecure-sentinel-values.yaml +++ /dev/null @@ -1,524 +0,0 @@ -## Global Docker image parameters -## Please, note that this will override the image parameters, including dependencies, configured to use the global value -## Current available global Docker image parameters: imageRegistry and imagePullSecrets -## -# global: -# imageRegistry: myRegistryName -# imagePullSecrets: -# - myRegistryKeySecretName - -## Bitnami Redis image version -## ref: https://hub.docker.com/r/bitnami/redis/tags/ -## -image: - registry: docker.io - repository: bitnami/redis - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.5-debian-9-r36 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - -## Redis pod Security Context -securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - -## Cluster settings -cluster: - enabled: true - slaveCount: 3 - -## Use redis sentinel in the redis pod. This will disable the master and slave services and -## create one redis service with ports to the sentinel and the redis instances -sentinel: - enabled: true - ## Require password authentication on the sentinel itself - ## ref: https://redis.io/topics/sentinel - usePassword: false - ## Bitnami Redis Sentintel image version - ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ - ## - image: - registry: docker.io - repository: bitnami/redis-sentinel - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.5-debian-9-r37 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - masterSet: mymaster - initialCheckTimeout: 5 - quorum: 2 - downAfterMilliseconds: 60000 - failoverTimeout: 18000 - parallelSyncs: 1 - port: 26379 - ## Configure extra options for Redis Sentinel liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - ## Redis Sentinel resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Redis Sentinel Service properties - service: - ## Redis Sentinel Service type - type: ClusterIP - sentinelPort: 26379 - redisPort: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # sentinelNodePort: - # redisNodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - -networkPolicy: - ## Specifies whether a NetworkPolicy should be created - ## - enabled: true - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port Redis is listening - ## on. When true, Redis will accept connections from any source - ## (with the correct destination port). - ## - # allowExternal: true - -serviceAccount: - ## Specifies whether a ServiceAccount should be created - ## - create: false - ## The name of the ServiceAccount to use. - ## If not set and create is true, a name is generated using the fullname template - name: - -rbac: - ## Specifies whether RBAC resources should be created - ## - create: false - - role: - ## Rules to create. It follows the role specification - # rules: - # - apiGroups: - # - extensions - # resources: - # - podsecuritypolicies - # verbs: - # - use - # resourceNames: - # - gce.unprivileged - rules: [] - - -## Use password authentication -usePassword: true -## Redis password (both master and slave) -## Defaults to a random 10-character alphanumeric string if not set and usePassword is true -## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run -## -password: -## Use existing secret (ignores previous password) -# existingSecret: -## Password key to be retrieved from Redis secret -## -# existingSecretPasswordKey: - -## Mount secrets as files instead of environment variables -usePasswordFile: false - -## Persist data to a persistent volume -persistence: {} - ## A manually managed Persistent Volume and Claim - ## Requires persistence.enabled: true - ## If defined, PVC must be created manually before volume will be bound - # existingClaim: - -# Redis port -redisPort: 6379 - -## -## Redis Master parameters -## -master: - ## Redis command arguments - ## - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Redis additional command line flags - ## - ## Can be used to specify command line flags, for example: - ## - ## extraFlags: - ## - "--maxmemory-policy volatile-ttl" - ## - "--repl-backlog-size 1024mb" - extraFlags: [] - ## Comma-separated list of Redis commands to disable - ## - ## Can be used to disable Redis commands for security reasons. - ## Commands will be completely disabled by renaming each to an empty string. - ## ref: https://redis.io/topics/security#disabling-of-specific-commands - ## - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Master additional pod labels and annotations - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - podLabels: {} - podAnnotations: {} - - ## Redis Master resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Configure extra options for Redis Master liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - - ## Redis Master Node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - ## Redis Master pod/node affinity/anti-affinity - ## - affinity: {} - - ## Redis Master Service properties - service: - ## Redis Master Service type - type: ClusterIP - port: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - ## Redis Master pod priorityClassName - # priorityClassName: {} - - -## -## Redis Slave properties -## Note: service.type is a mandatory parameter -## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master -## -slave: - ## Slave Service properties - service: - ## Redis Slave Service type - type: ClusterIP - ## Redis port - port: 6379 - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - - ## Redis slave port - port: 6379 - - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Redis extra flags - extraFlags: [] - ## List of Redis commands to disable - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Slave pod/node affinity/anti-affinity - ## - affinity: {} - - ## Configure extra options for Redis Slave liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 10 - successThreshold: 1 - failureThreshold: 5 - - ## Redis slave Resource - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - ## Redis slave selectors and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Redis slave pod Annotation and Labels - podLabels: {} - podAnnotations: {} - - ## Redis slave pod priorityClassName - # priorityClassName: {} - -## Prometheus Exporter / Metrics -## -metrics: - enabled: true - - image: - registry: docker.io - repository: bitnami/redis-exporter - tag: 1.0.3-debian-9-r0 - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - - ## Metrics exporter resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - # resources: {} - ## Metrics exporter pod priorityClassName - # priorityClassName: {} - service: - type: ClusterIP - ## Use serviceLoadBalancerIP to request a specific static IP, - ## otherwise leave blank - # loadBalancerIP: - annotations: {} - - ## Extra arguments for Metrics exporter, for example: - ## extraArgs: - ## check-keys: myKey,myOtherKey - # extraArgs: {} - - ## Metrics exporter pod Annotation and Labels - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "9121" - # podLabels: {} - - # Enable this if you're using https://github.com/coreos/prometheus-operator - serviceMonitor: - enabled: false - ## Specify a namespace if needed - # namespace: monitoring - # fallback to the prometheus default unless specified - # interval: 10s - ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) - ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) - ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) - selector: - prometheus: kube-prometheus -## -## Init containers parameters: -## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup -## -volumePermissions: - enabled: false - image: - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m - -## Redis config file -## ref: https://redis.io/topics/config -## -configmap: |- - # maxmemory-policy volatile-lru - -## Sysctl InitContainer -## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) -sysctlImage: - enabled: false - command: [] - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - mountHostSys: false - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m diff --git a/infra/charts/feast/charts/redis/ci/production-sentinel-values.yaml b/infra/charts/feast/charts/redis/ci/production-sentinel-values.yaml deleted file mode 100644 index 36a00e37fb9..00000000000 --- a/infra/charts/feast/charts/redis/ci/production-sentinel-values.yaml +++ /dev/null @@ -1,524 +0,0 @@ -## Global Docker image parameters -## Please, note that this will override the image parameters, including dependencies, configured to use the global value -## Current available global Docker image parameters: imageRegistry and imagePullSecrets -## -# global: -# imageRegistry: myRegistryName -# imagePullSecrets: -# - myRegistryKeySecretName - -## Bitnami Redis image version -## ref: https://hub.docker.com/r/bitnami/redis/tags/ -## -image: - registry: docker.io - repository: bitnami/redis - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.5-debian-9-r36 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - -## Redis pod Security Context -securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - -## Cluster settings -cluster: - enabled: true - slaveCount: 3 - -## Use redis sentinel in the redis pod. This will disable the master and slave services and -## create one redis service with ports to the sentinel and the redis instances -sentinel: - enabled: true - ## Require password authentication on the sentinel itself - ## ref: https://redis.io/topics/sentinel - usePassword: true - ## Bitnami Redis Sentintel image version - ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ - ## - image: - registry: docker.io - repository: bitnami/redis-sentinel - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.5-debian-9-r37 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - masterSet: mymaster - initialCheckTimeout: 5 - quorum: 2 - downAfterMilliseconds: 60000 - failoverTimeout: 18000 - parallelSyncs: 1 - port: 26379 - ## Configure extra options for Redis Sentinel liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - ## Redis Sentinel resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Redis Sentinel Service properties - service: - ## Redis Sentinel Service type - type: ClusterIP - sentinelPort: 26379 - redisPort: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # sentinelNodePort: - # redisNodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - -networkPolicy: - ## Specifies whether a NetworkPolicy should be created - ## - enabled: true - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port Redis is listening - ## on. When true, Redis will accept connections from any source - ## (with the correct destination port). - ## - # allowExternal: true - -serviceAccount: - ## Specifies whether a ServiceAccount should be created - ## - create: false - ## The name of the ServiceAccount to use. - ## If not set and create is true, a name is generated using the fullname template - name: - -rbac: - ## Specifies whether RBAC resources should be created - ## - create: false - - role: - ## Rules to create. It follows the role specification - # rules: - # - apiGroups: - # - extensions - # resources: - # - podsecuritypolicies - # verbs: - # - use - # resourceNames: - # - gce.unprivileged - rules: [] - - -## Use password authentication -usePassword: true -## Redis password (both master and slave) -## Defaults to a random 10-character alphanumeric string if not set and usePassword is true -## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run -## -password: -## Use existing secret (ignores previous password) -# existingSecret: -## Password key to be retrieved from Redis secret -## -# existingSecretPasswordKey: - -## Mount secrets as files instead of environment variables -usePasswordFile: false - -## Persist data to a persistent volume -persistence: {} - ## A manually managed Persistent Volume and Claim - ## Requires persistence.enabled: true - ## If defined, PVC must be created manually before volume will be bound - # existingClaim: - -# Redis port -redisPort: 6379 - -## -## Redis Master parameters -## -master: - ## Redis command arguments - ## - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Redis additional command line flags - ## - ## Can be used to specify command line flags, for example: - ## - ## extraFlags: - ## - "--maxmemory-policy volatile-ttl" - ## - "--repl-backlog-size 1024mb" - extraFlags: [] - ## Comma-separated list of Redis commands to disable - ## - ## Can be used to disable Redis commands for security reasons. - ## Commands will be completely disabled by renaming each to an empty string. - ## ref: https://redis.io/topics/security#disabling-of-specific-commands - ## - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Master additional pod labels and annotations - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - podLabels: {} - podAnnotations: {} - - ## Redis Master resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Configure extra options for Redis Master liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - - ## Redis Master Node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - ## Redis Master pod/node affinity/anti-affinity - ## - affinity: {} - - ## Redis Master Service properties - service: - ## Redis Master Service type - type: ClusterIP - port: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - ## Redis Master pod priorityClassName - # priorityClassName: {} - - -## -## Redis Slave properties -## Note: service.type is a mandatory parameter -## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master -## -slave: - ## Slave Service properties - service: - ## Redis Slave Service type - type: ClusterIP - ## Redis port - port: 6379 - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - - ## Redis slave port - port: 6379 - - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Redis extra flags - extraFlags: [] - ## List of Redis commands to disable - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Slave pod/node affinity/anti-affinity - ## - affinity: {} - - ## Configure extra options for Redis Slave liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 10 - successThreshold: 1 - failureThreshold: 5 - - ## Redis slave Resource - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - ## Redis slave selectors and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Redis slave pod Annotation and Labels - podLabels: {} - podAnnotations: {} - - ## Redis slave pod priorityClassName - # priorityClassName: {} - -## Prometheus Exporter / Metrics -## -metrics: - enabled: true - - image: - registry: docker.io - repository: bitnami/redis-exporter - tag: 1.0.3-debian-9-r0 - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - - ## Metrics exporter resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - # resources: {} - ## Metrics exporter pod priorityClassName - # priorityClassName: {} - service: - type: ClusterIP - ## Use serviceLoadBalancerIP to request a specific static IP, - ## otherwise leave blank - # loadBalancerIP: - annotations: {} - - ## Extra arguments for Metrics exporter, for example: - ## extraArgs: - ## check-keys: myKey,myOtherKey - # extraArgs: {} - - ## Metrics exporter pod Annotation and Labels - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "9121" - # podLabels: {} - - # Enable this if you're using https://github.com/coreos/prometheus-operator - serviceMonitor: - enabled: false - ## Specify a namespace if needed - # namespace: monitoring - # fallback to the prometheus default unless specified - # interval: 10s - ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) - ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) - ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) - selector: - prometheus: kube-prometheus -## -## Init containers parameters: -## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup -## -volumePermissions: - enabled: false - image: - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m - -## Redis config file -## ref: https://redis.io/topics/config -## -configmap: |- - # maxmemory-policy volatile-lru - -## Sysctl InitContainer -## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) -sysctlImage: - enabled: false - command: [] - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - mountHostSys: false - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m diff --git a/infra/charts/feast/charts/redis/ci/production-values.yaml b/infra/charts/feast/charts/redis/ci/production-values.yaml deleted file mode 100644 index 6fa9c88ad3b..00000000000 --- a/infra/charts/feast/charts/redis/ci/production-values.yaml +++ /dev/null @@ -1,525 +0,0 @@ -## Global Docker image parameters -## Please, note that this will override the image parameters, including dependencies, configured to use the global value -## Current available global Docker image parameters: imageRegistry and imagePullSecrets -## -# global: -# imageRegistry: myRegistryName -# imagePullSecrets: -# - myRegistryKeySecretName - -## Bitnami Redis image version -## ref: https://hub.docker.com/r/bitnami/redis/tags/ -## -image: - registry: docker.io - repository: bitnami/redis - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.5-debian-9-r36 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - -## Redis pod Security Context -securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - -## Cluster settings -cluster: - enabled: true - slaveCount: 3 - -## Use redis sentinel in the redis pod. This will disable the master and slave services and -## create one redis service with ports to the sentinel and the redis instances -sentinel: - enabled: false - ## Require password authentication on the sentinel itself - ## ref: https://redis.io/topics/sentinel - usePassword: true - ## Bitnami Redis Sentintel image version - ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ - ## - image: - registry: docker.io - repository: bitnami/redis-sentinel - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.5-debian-9-r37 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - masterSet: mymaster - initialCheckTimeout: 5 - quorum: 2 - downAfterMilliseconds: 60000 - failoverTimeout: 18000 - parallelSyncs: 1 - port: 26379 - ## Configure extra options for Redis Sentinel liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - ## Redis Sentinel resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Redis Sentinel Service properties - service: - ## Redis Sentinel Service type - type: ClusterIP - sentinelPort: 26379 - redisPort: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # sentinelNodePort: - # redisNodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - -networkPolicy: - ## Specifies whether a NetworkPolicy should be created - ## - enabled: true - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port Redis is listening - ## on. When true, Redis will accept connections from any source - ## (with the correct destination port). - ## - # allowExternal: true - -serviceAccount: - ## Specifies whether a ServiceAccount should be created - ## - create: false - ## The name of the ServiceAccount to use. - ## If not set and create is true, a name is generated using the fullname template - name: - -rbac: - ## Specifies whether RBAC resources should be created - ## - create: false - - role: - ## Rules to create. It follows the role specification - # rules: - # - apiGroups: - # - extensions - # resources: - # - podsecuritypolicies - # verbs: - # - use - # resourceNames: - # - gce.unprivileged - rules: [] - - -## Use password authentication -usePassword: true -## Redis password (both master and slave) -## Defaults to a random 10-character alphanumeric string if not set and usePassword is true -## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run -## -password: -## Use existing secret (ignores previous password) -# existingSecret: -## Password key to be retrieved from Redis secret -## -# existingSecretPasswordKey: - -## Mount secrets as files instead of environment variables -usePasswordFile: false - -## Persist data to a persistent volume -persistence: {} - ## A manually managed Persistent Volume and Claim - ## Requires persistence.enabled: true - ## If defined, PVC must be created manually before volume will be bound - # existingClaim: - -# Redis port -redisPort: 6379 - -## -## Redis Master parameters -## -master: - ## Redis command arguments - ## - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Redis additional command line flags - ## - ## Can be used to specify command line flags, for example: - ## - ## extraFlags: - ## - "--maxmemory-policy volatile-ttl" - ## - "--repl-backlog-size 1024mb" - extraFlags: [] - ## Comma-separated list of Redis commands to disable - ## - ## Can be used to disable Redis commands for security reasons. - ## Commands will be completely disabled by renaming each to an empty string. - ## ref: https://redis.io/topics/security#disabling-of-specific-commands - ## - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Master additional pod labels and annotations - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - podLabels: {} - podAnnotations: {} - - ## Redis Master resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Configure extra options for Redis Master liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - - ## Redis Master Node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - ## Redis Master pod/node affinity/anti-affinity - ## - affinity: {} - - ## Redis Master Service properties - service: - ## Redis Master Service type - type: ClusterIP - port: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - ## Redis Master pod priorityClassName - # priorityClassName: {} - - -## -## Redis Slave properties -## Note: service.type is a mandatory parameter -## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master -## -slave: - ## Slave Service properties - service: - ## Redis Slave Service type - type: ClusterIP - ## Redis port - port: 6379 - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - - ## Redis slave port - port: 6379 - - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Redis extra flags - extraFlags: [] - ## List of Redis commands to disable - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Slave pod/node affinity/anti-affinity - ## - affinity: {} - - ## Configure extra options for Redis Slave liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 10 - successThreshold: 1 - failureThreshold: 5 - - ## Redis slave Resource - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - ## Redis slave selectors and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Redis slave pod Annotation and Labels - podLabels: {} - podAnnotations: {} - - ## Redis slave pod priorityClassName - # priorityClassName: {} - -## Prometheus Exporter / Metrics -## -metrics: - enabled: true - - image: - registry: docker.io - repository: bitnami/redis-exporter - tag: 1.0.3-debian-9-r0 - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - - ## Metrics exporter resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - # resources: {} - - ## Extra arguments for Metrics exporter, for example: - ## extraArgs: - ## check-keys: myKey,myOtherKey - # extraArgs: {} - ## Metrics exporter pod priorityClassName - # priorityClassName: {} - service: - type: ClusterIP - ## Use serviceLoadBalancerIP to request a specific static IP, - ## otherwise leave blank - # loadBalancerIP: - annotations: {} - - ## Metrics exporter pod Annotation and Labels - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "9121" - # podLabels: {} - - # Enable this if you're using https://github.com/coreos/prometheus-operator - serviceMonitor: - enabled: false - ## Specify a namespace if needed - # namespace: monitoring - # fallback to the prometheus default unless specified - # interval: 10s - ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) - ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) - ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) - selector: - prometheus: kube-prometheus - -## -## Init containers parameters: -## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup -## -volumePermissions: - enabled: false - image: - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m - -## Redis config file -## ref: https://redis.io/topics/config -## -configmap: |- - # maxmemory-policy volatile-lru - -## Sysctl InitContainer -## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) -sysctlImage: - enabled: false - command: [] - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - mountHostSys: false - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m diff --git a/infra/charts/feast/charts/redis/ci/redis-lib-values.yaml b/infra/charts/feast/charts/redis/ci/redis-lib-values.yaml deleted file mode 100644 index e03382b55ea..00000000000 --- a/infra/charts/feast/charts/redis/ci/redis-lib-values.yaml +++ /dev/null @@ -1,13 +0,0 @@ -## Redis library image -## ref: https://hub.docker.com/r/library/redis/ -## -image: - registry: docker.io - repository: redis - tag: '5.0.5' - -master: - command: "redis-server" - -slave: - command: "redis-server" diff --git a/infra/charts/feast/charts/redis/ci/redisgraph-module-values.yaml b/infra/charts/feast/charts/redis/ci/redisgraph-module-values.yaml deleted file mode 100644 index 80960203ca0..00000000000 --- a/infra/charts/feast/charts/redis/ci/redisgraph-module-values.yaml +++ /dev/null @@ -1,10 +0,0 @@ -image: - registry: docker.io - repository: redislabs/redisgraph - tag: '1.0.0' - -master: - command: "redis-server" - -slave: - command: "redis-server" diff --git a/infra/charts/feast/charts/redis/templates/NOTES.txt b/infra/charts/feast/charts/redis/templates/NOTES.txt deleted file mode 100644 index 5b1089e8bec..00000000000 --- a/infra/charts/feast/charts/redis/templates/NOTES.txt +++ /dev/null @@ -1,104 +0,0 @@ -** Please be patient while the chart is being deployed ** - -{{- if contains .Values.master.service.type "LoadBalancer" }} -{{- if not .Values.usePassword }} -{{ if and (not .Values.networkPolicy.enabled) (.Values.networkPolicy.allowExternal) }} - -------------------------------------------------------------------------------- - WARNING - - By specifying "master.service.type=LoadBalancer" and "usePassword=false" you have - most likely exposed the Redis service externally without any authentication - mechanism. - - For security reasons, we strongly suggest that you switch to "ClusterIP" or - "NodePort". As alternative, you can also switch to "usePassword=true" - providing a valid password on "password" parameter. - -------------------------------------------------------------------------------- -{{- end }} -{{- end }} -{{- end }} - -{{- if .Values.cluster.enabled }} -{{- if .Values.sentinel.enabled }} -Redis can be accessed via port {{ .Values.sentinel.service.redisPort }} on the following DNS name from within your cluster: - -{{ template "redis.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read only operations - -For read/write operations, first access the Redis Sentinel cluster, which is available in port {{ .Values.sentinel.service.sentinelPort }} using the same domain name above. - -{{- else }} -Redis can be accessed via port {{ .Values.redisPort }} on the following DNS names from within your cluster: - -{{ template "redis.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read/write operations -{{ template "redis.fullname" . }}-slave.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read-only operations -{{- end }} - -{{- else }} -Redis can be accessed via port {{ .Values.redisPort }} on the following DNS name from within your cluster: - -{{ template "redis.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} - -{{- end }} - -{{ if .Values.usePassword }} -To get your password run: - - export REDIS_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "redis.secretName" . }} -o jsonpath="{.data.redis-password}" | base64 --decode) -{{- end }} - -To connect to your Redis server: - -1. Run a Redis pod that you can use as a client: - - kubectl run --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }}-client --rm --tty -i --restart='Never' \ - {{ if .Values.usePassword }} --env REDIS_PASSWORD=$REDIS_PASSWORD \{{ end }} - {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}--labels="{{ template "redis.fullname" . }}-client=true" \{{- end }} - --image {{ template "redis.image" . }} -- bash - -2. Connect using the Redis CLI: - -{{- if .Values.cluster.enabled }} - {{- if .Values.sentinel.enabled }} - redis-cli -h {{ template "redis.fullname" . }} -p {{ .Values.sentinel.service.redisPort }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} # Read only operations - redis-cli -h {{ template "redis.fullname" . }} -p {{ .Values.sentinel.service.sentinelPort }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} # Sentinel access - {{- else }} - redis-cli -h {{ template "redis.fullname" . }}-master{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - redis-cli -h {{ template "redis.fullname" . }}-slave{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - {{- end }} -{{- else }} - redis-cli -h {{ template "redis.fullname" . }}-master{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} -{{- end }} - -{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} -Note: Since NetworkPolicy is enabled, only pods with label -{{ template "redis.fullname" . }}-client=true" -will be able to connect to redis. -{{- else -}} - -To connect to your database from outside the cluster execute the following commands: - -{{- if contains "NodePort" .Values.master.service.type }} - - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "redis.fullname" . }}-master) - redis-cli -h $NODE_IP -p $NODE_PORT {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - -{{- else if contains "LoadBalancer" .Values.master.service.type }} - - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "redis.fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - redis-cli -h $SERVICE_IP -p {{ .Values.master.service.port }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - -{{- else if contains "ClusterIP" .Values.master.service.type }} - - kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "redis.fullname" . }}-master {{ .Values.redisPort }}:{{ .Values.redisPort }} & - redis-cli -h 127.0.0.1 -p {{ .Values.redisPort }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - -{{- end }} -{{- end }} - -{{ include "redis.checkRollingTags" . }} diff --git a/infra/charts/feast/charts/redis/templates/_helpers.tpl b/infra/charts/feast/charts/redis/templates/_helpers.tpl deleted file mode 100644 index 3397a7b6c70..00000000000 --- a/infra/charts/feast/charts/redis/templates/_helpers.tpl +++ /dev/null @@ -1,355 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "redis.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Expand the chart plus release name (used by the chart label) -*/}} -{{- define "redis.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version -}} -{{- 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 "redis.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 -}} - -{{/* -Return the appropriate apiVersion for networkpolicy. -*/}} -{{- define "networkPolicy.apiVersion" -}} -{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "extensions/v1beta1" -}} -{{- else -}} -{{- print "networking.k8s.io/v1" -}} -{{- end -}} -{{- end -}} - -{{/* -Return the appropriate apiGroup for PodSecurityPolicy. -*/}} -{{- define "podSecurityPolicy.apiGroup" -}} -{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "policy" -}} -{{- else -}} -{{- print "extensions" -}} -{{- end -}} -{{- end -}} - -{{/* -Return the appropriate apiVersion for PodSecurityPolicy. -*/}} -{{- define "podSecurityPolicy.apiVersion" -}} -{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "policy/v1beta1" -}} -{{- else -}} -{{- print "extensions/v1beta1" -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper Redis image name -*/}} -{{- define "redis.image" -}} -{{- $registryName := .Values.image.registry -}} -{{- $repositoryName := .Values.image.repository -}} -{{- $tag := .Values.image.tag | toString -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. -Also, we can't use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} - {{- if .Values.global.imageRegistry }} - {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} - {{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} - {{- end -}} -{{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper Redis Sentinel image name -*/}} -{{- define "sentinel.image" -}} -{{- $registryName := .Values.sentinel.image.registry -}} -{{- $repositoryName := .Values.sentinel.image.repository -}} -{{- $tag := .Values.sentinel.image.tag | toString -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. -Also, we can't use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} - {{- if .Values.global.imageRegistry }} - {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} - {{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} - {{- end -}} -{{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper image name (for the metrics image) -*/}} -{{- define "redis.metrics.image" -}} -{{- $registryName := .Values.metrics.image.registry -}} -{{- $repositoryName := .Values.metrics.image.repository -}} -{{- $tag := .Values.metrics.image.tag | toString -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. -Also, we can't use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} - {{- if .Values.global.imageRegistry }} - {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} - {{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} - {{- end -}} -{{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper image name (for the init container volume-permissions image) -*/}} -{{- define "redis.volumePermissions.image" -}} -{{- $registryName := .Values.volumePermissions.image.registry -}} -{{- $repositoryName := .Values.volumePermissions.image.repository -}} -{{- $tag := .Values.volumePermissions.image.tag | toString -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. -Also, we can't use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} - {{- if .Values.global.imageRegistry }} - {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} - {{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} - {{- end -}} -{{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} -{{- end -}} - -{{/* -Create the name of the service account to use -*/}} -{{- define "redis.serviceAccountName" -}} -{{- if .Values.serviceAccount.create -}} - {{ default (include "redis.fullname" .) .Values.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* -Get the password secret. -*/}} -{{- define "redis.secretName" -}} -{{- if .Values.existingSecret -}} -{{- printf "%s" .Values.existingSecret -}} -{{- else -}} -{{- printf "%s" (include "redis.fullname" .) -}} -{{- end -}} -{{- end -}} - -{{/* -Get the password key to be retrieved from Redis secret. -*/}} -{{- define "redis.secretPasswordKey" -}} -{{- if and .Values.existingSecret .Values.existingSecretPasswordKey -}} -{{- printf "%s" .Values.existingSecretPasswordKey -}} -{{- else -}} -{{- printf "redis-password" -}} -{{- end -}} -{{- end -}} - -{{/* -Return Redis password -*/}} -{{- define "redis.password" -}} -{{- if not (empty .Values.global.redis.password) }} - {{- .Values.global.redis.password -}} -{{- else if not (empty .Values.password) -}} - {{- .Values.password -}} -{{- else -}} - {{- randAlphaNum 10 -}} -{{- end -}} -{{- end -}} - -{{/* -Return sysctl image -*/}} -{{- define "redis.sysctl.image" -}} -{{- $registryName := default "docker.io" .Values.sysctlImage.registry -}} -{{- $repositoryName := .Values.sysctlImage.repository -}} -{{- $tag := default "buster" .Values.sysctlImage.tag | toString -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic. -Also, we can't use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} - {{- if .Values.global.imageRegistry }} - {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}} - {{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} - {{- end -}} -{{- else -}} - {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper Docker Image Registry Secret Names -*/}} -{{- define "redis.imagePullSecrets" -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. -Also, we can not use a single if because lazy evaluation is not an option -*/}} -{{- if .Values.global }} -{{- if .Values.global.imagePullSecrets }} -imagePullSecrets: -{{- range .Values.global.imagePullSecrets }} - - name: {{ . }} -{{- end }} -{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets .Values.sysctlImage.pullSecrets .Values.volumePermissions.image.pullSecrets }} -imagePullSecrets: -{{- range .Values.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.metrics.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.sysctlImage.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.volumePermissions.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- end -}} -{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets .Values.sysctlImage.pullSecrets .Values.volumePermissions.image.pullSecrets }} -imagePullSecrets: -{{- range .Values.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.metrics.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.sysctlImage.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- range .Values.volumePermissions.image.pullSecrets }} - - name: {{ . }} -{{- end }} -{{- end -}} -{{- end -}} - -{{/* Check if there are rolling tags in the images */}} -{{- define "redis.checkRollingTags" -}} -{{- if and (contains "bitnami/" .Values.image.repository) (not (.Values.image.tag | toString | regexFind "-r\\d+$|sha256:")) }} -WARNING: Rolling tag detected ({{ .Values.image.repository }}:{{ .Values.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. -+info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ -{{- end }} -{{- if and (contains "bitnami/" .Values.sentinel.image.repository) (not (.Values.sentinel.image.tag | toString | regexFind "-r\\d+$|sha256:")) }} -WARNING: Rolling tag detected ({{ .Values.sentinel.image.repository }}:{{ .Values.sentinel.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. -+info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ -{{- end }} -{{- end -}} - -{{/* -Return the proper Storage Class for master -*/}} -{{- define "redis.master.storageClass" -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. -*/}} -{{- if .Values.global -}} - {{- if .Values.global.storageClass -}} - {{- if (eq "-" .Values.global.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.global.storageClass -}} - {{- end -}} - {{- else -}} - {{- if .Values.master.persistence.storageClass -}} - {{- if (eq "-" .Values.master.persistence.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.master.persistence.storageClass -}} - {{- end -}} - {{- end -}} - {{- end -}} -{{- else -}} - {{- if .Values.master.persistence.storageClass -}} - {{- if (eq "-" .Values.master.persistence.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.master.persistence.storageClass -}} - {{- end -}} - {{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper Storage Class for slave -*/}} -{{- define "redis.slave.storageClass" -}} -{{/* -Helm 2.11 supports the assignment of a value to a variable defined in a different scope, -but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. -*/}} -{{- if .Values.global -}} - {{- if .Values.global.storageClass -}} - {{- if (eq "-" .Values.global.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.global.storageClass -}} - {{- end -}} - {{- else -}} - {{- if .Values.slave.persistence.storageClass -}} - {{- if (eq "-" .Values.slave.persistence.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.slave.persistence.storageClass -}} - {{- end -}} - {{- end -}} - {{- end -}} -{{- else -}} - {{- if .Values.slave.persistence.storageClass -}} - {{- if (eq "-" .Values.slave.persistence.storageClass) -}} - {{- printf "storageClassName: \"\"" -}} - {{- else }} - {{- printf "storageClassName: %s" .Values.slave.persistence.storageClass -}} - {{- end -}} - {{- end -}} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/configmap.yaml b/infra/charts/feast/charts/redis/templates/configmap.yaml deleted file mode 100644 index d17ec26abf9..00000000000 --- a/infra/charts/feast/charts/redis/templates/configmap.yaml +++ /dev/null @@ -1,52 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -data: - redis.conf: |- -{{- if .Values.configmap }} - # User-supplied configuration: -{{ tpl .Values.configmap . | indent 4 }} -{{- end }} - master.conf: |- - dir {{ .Values.master.persistence.path }} -{{- if .Values.master.configmap }} - # User-supplied master configuration: -{{ tpl .Values.master.configmap . | indent 4 }} -{{- end }} -{{- if .Values.master.disableCommands }} -{{- range .Values.master.disableCommands }} - rename-command {{ . }} "" -{{- end }} -{{- end }} - replica.conf: |- - dir {{ .Values.slave.persistence.path }} - slave-read-only yes -{{- if .Values.slave.configmap }} - # User-supplied slave configuration: -{{ tpl .Values.slave.configmap . | indent 4 }} -{{- end }} -{{- if .Values.slave.disableCommands }} -{{- range .Values.slave.disableCommands }} - rename-command {{ . }} "" -{{- end }} -{{- end }} -{{- if .Values.sentinel.enabled }} - sentinel.conf: |- - dir "/tmp" - bind 0.0.0.0 - port {{ .Values.sentinel.port }} - sentinel monitor {{ .Values.sentinel.masterSet }} {{ template "redis.fullname" . }}-master-0.{{ template "redis.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} {{ .Values.redisPort }} {{ .Values.sentinel.quorum }} - sentinel down-after-milliseconds {{ .Values.sentinel.masterSet }} {{ .Values.sentinel.downAfterMilliseconds }} - sentinel failover-timeout {{ .Values.sentinel.masterSet }} {{ .Values.sentinel.failoverTimeout }} - sentinel parallel-syncs {{ .Values.sentinel.masterSet }} {{ .Values.sentinel.parallelSyncs }} -{{- if .Values.sentinel.configmap }} - # User-supplied sentinel configuration: -{{ tpl .Values.sentinel.configmap . | indent 4 }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/headless-svc.yaml b/infra/charts/feast/charts/redis/templates/headless-svc.yaml deleted file mode 100644 index 909cbceafd1..00000000000 --- a/infra/charts/feast/charts/redis/templates/headless-svc.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "redis.fullname" . }}-headless - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - type: ClusterIP - clusterIP: None - ports: - - name: redis - port: {{ .Values.redisPort }} - targetPort: redis -{{- if .Values.sentinel.enabled }} - - name: redis-sentinel - port: {{ .Values.sentinel.port }} - targetPort: redis-sentinel -{{- end }} - selector: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} diff --git a/infra/charts/feast/charts/redis/templates/health-configmap.yaml b/infra/charts/feast/charts/redis/templates/health-configmap.yaml deleted file mode 100644 index 35c61b5ad20..00000000000 --- a/infra/charts/feast/charts/redis/templates/health-configmap.yaml +++ /dev/null @@ -1,134 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "redis.fullname" . }}-health - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -data: - ping_readiness_local.sh: |- -{{- if .Values.usePasswordFile }} - password_aux=`cat ${REDIS_PASSWORD_FILE}` - export REDIS_PASSWORD=$password_aux -{{- end }} - response=$( - timeout -s 9 $1 \ - redis-cli \ -{{- if .Values.usePassword }} - -a $REDIS_PASSWORD --no-auth-warning \ -{{- end }} - -h localhost \ - -p $REDIS_PORT \ - ping - ) - if [ "$response" != "PONG" ]; then - echo "$response" - exit 1 - fi - ping_liveness_local.sh: |- -{{- if .Values.usePasswordFile }} - password_aux=`cat ${REDIS_PASSWORD_FILE}` - export REDIS_PASSWORD=$password_aux -{{- end }} - response=$( - timeout -s 9 $1 \ - redis-cli \ -{{- if .Values.usePassword }} - -a $REDIS_PASSWORD --no-auth-warning \ -{{- end }} - -h localhost \ - -p $REDIS_PORT \ - ping - ) - if [ "$response" != "PONG" ] && [ "$response" != "LOADING Redis is loading the dataset in memory" ]; then - echo "$response" - exit 1 - fi -{{- if .Values.sentinel.enabled }} - ping_sentinel.sh: |- -{{- if .Values.usePasswordFile }} - password_aux=`cat ${REDIS_PASSWORD_FILE}` - export REDIS_PASSWORD=$password_aux -{{- end }} - response=$( - timeout -s 9 $1 \ - redis-cli \ -{{- if .Values.usePassword }} - -a $REDIS_PASSWORD --no-auth-warning \ -{{- end }} - -h localhost \ - -p $REDIS_SENTINEL_PORT \ - ping - ) - if [ "$response" != "PONG" ]; then - echo "$response" - exit 1 - fi - parse_sentinels.awk: |- - /ip/ {FOUND_IP=1} - /port/ {FOUND_PORT=1} - /runid/ {FOUND_RUNID=1} - !/ip|port|runid/ { - if (FOUND_IP==1) { - IP=$1; FOUND_IP=0; - } - else if (FOUND_PORT==1) { - PORT=$1; - FOUND_PORT=0; - } else if (FOUND_RUNID==1) { - printf "\nsentinel known-sentinel {{ .Values.sentinel.masterSet }} %s %s %s", IP, PORT, $0; FOUND_RUNID=0; - } - } -{{- end }} - ping_readiness_master.sh: |- -{{- if .Values.usePasswordFile }} - password_aux=`cat ${REDIS_MASTER_PASSWORD_FILE}` - export REDIS_MASTER_PASSWORD=$password_aux -{{- end }} - response=$( - timeout -s 9 $1 \ - redis-cli \ -{{- if .Values.usePassword }} - -a $REDIS_MASTER_PASSWORD --no-auth-warning \ -{{- end }} - -h $REDIS_MASTER_HOST \ - -p $REDIS_MASTER_PORT_NUMBER \ - ping - ) - if [ "$response" != "PONG" ]; then - echo "$response" - exit 1 - fi - ping_liveness_master.sh: |- -{{- if .Values.usePasswordFile }} - password_aux=`cat ${REDIS_MASTER_PASSWORD_FILE}` - export REDIS_MASTER_PASSWORD=$password_aux -{{- end }} - response=$( - timeout -s 9 $1 \ - redis-cli \ -{{- if .Values.usePassword }} - -a $REDIS_MASTER_PASSWORD --no-auth-warning \ -{{- end }} - -h $REDIS_MASTER_HOST \ - -p $REDIS_MASTER_PORT_NUMBER \ - ping - ) - if [ "$response" != "PONG" ] && [ "$response" != "LOADING Redis is loading the dataset in memory" ]; then - echo "$response" - exit 1 - fi - ping_readiness_local_and_master.sh: |- - script_dir="$(dirname "$0")" - exit_status=0 - "$script_dir/ping_readiness_local.sh" $1 || exit_status=$? - "$script_dir/ping_readiness_master.sh" $1 || exit_status=$? - exit $exit_status - ping_liveness_local_and_master.sh: |- - script_dir="$(dirname "$0")" - exit_status=0 - "$script_dir/ping_liveness_local.sh" $1 || exit_status=$? - "$script_dir/ping_liveness_master.sh" $1 || exit_status=$? - exit $exit_status diff --git a/infra/charts/feast/charts/redis/templates/metrics-prometheus.yaml b/infra/charts/feast/charts/redis/templates/metrics-prometheus.yaml deleted file mode 100644 index 3f3345430f9..00000000000 --- a/infra/charts/feast/charts/redis/templates/metrics-prometheus.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if and (.Values.metrics.enabled) (.Values.metrics.serviceMonitor.enabled) }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "redis.fullname" . }} - {{- if .Values.metrics.serviceMonitor.namespace }} - namespace: {{ .Values.metrics.serviceMonitor.namespace }} - {{- end }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - {{- range $key, $value := .Values.metrics.serviceMonitor.selector }} - {{ $key }}: {{ $value | quote }} - {{- end }} -spec: - endpoints: - - port: metrics - {{- if .Values.metrics.serviceMonitor.interval }} - interval: {{ .Values.metrics.serviceMonitor.interval }} - {{- end }} - selector: - matchLabels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} -{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/metrics-svc.yaml b/infra/charts/feast/charts/redis/templates/metrics-svc.yaml deleted file mode 100644 index 74f6fa85294..00000000000 --- a/infra/charts/feast/charts/redis/templates/metrics-svc.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.metrics.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "redis.fullname" . }}-metrics - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - {{- if .Values.metrics.service.labels -}} - {{ toYaml .Values.metrics.service.labels | nindent 4 }} - {{- end -}} - {{- if .Values.metrics.service.annotations }} - annotations: {{ toYaml .Values.metrics.service.annotations | nindent 4 }} - {{- end }} -spec: - type: {{ .Values.metrics.service.type }} - {{ if eq .Values.metrics.service.type "LoadBalancer" -}} {{ if .Values.metrics.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.metrics.service.loadBalancerIP }} - {{ end -}} - {{- end -}} - ports: - - name: metrics - port: 9121 - targetPort: metrics - selector: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/networkpolicy.yaml b/infra/charts/feast/charts/redis/templates/networkpolicy.yaml deleted file mode 100644 index da055527cc7..00000000000 --- a/infra/charts/feast/charts/redis/templates/networkpolicy.yaml +++ /dev/null @@ -1,73 +0,0 @@ -{{- if .Values.networkPolicy.enabled }} -kind: NetworkPolicy -apiVersion: {{ template "networkPolicy.apiVersion" . }} -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - podSelector: - matchLabels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - {{- if .Values.cluster.enabled }} - policyTypes: - - Ingress - - Egress - egress: - # Allow dns resolution - - ports: - - port: 53 - protocol: UDP - # Allow outbound connections to other cluster pods - - ports: - - port: {{ .Values.redisPort }} - {{- if .Values.sentinel.enabled }} - - port: {{ .Values.sentinel.port }} - {{- end }} - to: - - podSelector: - matchLabels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - {{- end }} - ingress: - # Allow inbound connections - - ports: - - port: {{ .Values.redisPort }} - {{- if .Values.sentinel.enabled }} - - port: {{ .Values.sentinel.port }} - {{- end }} - {{- if not .Values.networkPolicy.allowExternal }} - from: - - podSelector: - matchLabels: - {{ template "redis.fullname" . }}-client: "true" - - podSelector: - matchLabels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - {{- if .Values.networkPolicy.ingressNSMatchLabels }} - - namespaceSelector: - matchLabels: - {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} - {{ $key | quote }}: {{ $value | quote }} - {{- end }} - {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} - podSelector: - matchLabels: - {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} - {{ $key | quote }}: {{ $value | quote }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} - {{- if .Values.metrics.enabled }} - # Allow prometheus scrapes for metrics - - ports: - - port: 9121 - {{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/prometheusrule.yaml b/infra/charts/feast/charts/redis/templates/prometheusrule.yaml deleted file mode 100644 index 500c3b37e73..00000000000 --- a/infra/charts/feast/charts/redis/templates/prometheusrule.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ template "redis.fullname" . }} -{{- with .Values.metrics.prometheusRule.namespace }} - namespace: {{ . }} -{{- end }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -{{- with .Values.metrics.prometheusRule.additionalLabels }} -{{ toYaml . | indent 4 }} -{{- end }} -spec: -{{- with .Values.metrics.prometheusRule.rules }} - groups: - - name: {{ template "redis.name" $ }} - rules: {{ tpl (toYaml .) $ | nindent 8 }} -{{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/psp.yaml b/infra/charts/feast/charts/redis/templates/psp.yaml deleted file mode 100644 index 28ae22a775a..00000000000 --- a/infra/charts/feast/charts/redis/templates/psp.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- if .Values.podSecurityPolicy.create }} -apiVersion: {{ template "podSecurityPolicy.apiVersion" . }} -kind: PodSecurityPolicy -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - allowPrivilegeEscalation: false - fsGroup: - rule: 'MustRunAs' - ranges: - - min: {{ .Values.securityContext.fsGroup }} - max: {{ .Values.securityContext.fsGroup }} - hostIPC: false - hostNetwork: false - hostPID: false - privileged: false - readOnlyRootFilesystem: false - requiredDropCapabilities: - - ALL - runAsUser: - rule: 'MustRunAs' - ranges: - - min: {{ .Values.securityContext.runAsUser }} - max: {{ .Values.securityContext.runAsUser }} - seLinux: - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: {{ .Values.securityContext.runAsUser }} - max: {{ .Values.securityContext.runAsUser }} - volumes: - - 'configMap' - - 'secret' - - 'emptyDir' - - 'persistentVolumeClaim' -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-master-statefulset.yaml b/infra/charts/feast/charts/redis/templates/redis-master-statefulset.yaml deleted file mode 100755 index b61c5391da7..00000000000 --- a/infra/charts/feast/charts/redis/templates/redis-master-statefulset.yaml +++ /dev/null @@ -1,419 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ template "redis.fullname" . }}-master - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - selector: - matchLabels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - role: master - serviceName: {{ template "redis.fullname" . }}-headless - template: - metadata: - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - role: master -{{- if .Values.master.podLabels }} -{{ toYaml .Values.master.podLabels | indent 8 }} -{{- end }} -{{- if and .Values.metrics.enabled .Values.metrics.podLabels }} -{{ toYaml .Values.metrics.podLabels | indent 8 }} -{{- end }} - annotations: - checksum/health: {{ include (print $.Template.BasePath "/health-configmap.yaml") . | sha256sum }} - checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} - checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} - {{- if .Values.master.podAnnotations }} -{{ toYaml .Values.master.podAnnotations | indent 8 }} - {{- end }} - {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} -{{ toYaml .Values.metrics.podAnnotations | indent 8 }} - {{- end }} - spec: -{{- include "redis.imagePullSecrets" . | indent 6 }} - {{- if .Values.securityContext.enabled }} - securityContext: - fsGroup: {{ .Values.securityContext.fsGroup }} - {{- if .Values.securityContext.sysctls }} - sysctls: -{{ toYaml .Values.securityContext.sysctls | indent 8 }} - {{- end }} - {{- end }} - serviceAccountName: "{{ template "redis.serviceAccountName" . }}" - {{- if .Values.master.priorityClassName }} - priorityClassName: "{{ .Values.master.priorityClassName }}" - {{- end }} - {{- with .Values.master.affinity }} - affinity: -{{ tpl (toYaml .) $ | indent 8 }} - {{- end }} - {{- if .Values.master.nodeSelector }} - nodeSelector: -{{ toYaml .Values.master.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.master.tolerations }} - tolerations: -{{ toYaml .Values.master.tolerations | indent 8 }} - {{- end }} - {{- if .Values.master.schedulerName }} - schedulerName: "{{ .Values.master.schedulerName }}" - {{- end }} - containers: - - name: {{ template "redis.fullname" . }} - image: "{{ template "redis.image" . }}" - imagePullPolicy: {{ .Values.image.pullPolicy | quote }} - {{- if .Values.securityContext.enabled }} - securityContext: - runAsUser: {{ .Values.securityContext.runAsUser }} - {{- end }} - command: - - /bin/bash - - -c - - | - {{- if (eq (.Values.securityContext.runAsUser | int) 0) }} - useradd redis - chown -R redis {{ .Values.master.persistence.path }} - {{- end }} - if [[ -n $REDIS_PASSWORD_FILE ]]; then - password_aux=`cat ${REDIS_PASSWORD_FILE}` - export REDIS_PASSWORD=$password_aux - fi - if [[ ! -f /opt/bitnami/redis/etc/master.conf ]];then - cp /opt/bitnami/redis/mounted-etc/master.conf /opt/bitnami/redis/etc/master.conf - fi - if [[ ! -f /opt/bitnami/redis/etc/redis.conf ]];then - cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf - fi - ARGS=("--port" "${REDIS_PORT}") - {{- if .Values.usePassword }} - ARGS+=("--requirepass" "${REDIS_PASSWORD}") - ARGS+=("--masterauth" "${REDIS_PASSWORD}") - {{- else }} - ARGS+=("--protected-mode" "no") - {{- end }} - ARGS+=("--include" "/opt/bitnami/redis/etc/redis.conf") - ARGS+=("--include" "/opt/bitnami/redis/etc/master.conf") - {{- if .Values.master.extraFlags }} - {{- range .Values.master.extraFlags }} - ARGS+=({{ . | quote }}) - {{- end }} - {{- end }} - {{- if .Values.master.command }} - {{ .Values.master.command }} ${ARGS[@]} - {{- else }} - redis-server "${ARGS[@]}" - {{- end }} - env: - - name: REDIS_REPLICATION_MODE - value: master - {{- if .Values.usePassword }} - {{- if .Values.usePasswordFile }} - - name: REDIS_PASSWORD_FILE - value: "/opt/bitnami/redis/secrets/redis-password" - {{- else }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "redis.secretName" . }} - key: {{ template "redis.secretPasswordKey" . }} - {{- end }} - {{- else }} - - name: ALLOW_EMPTY_PASSWORD - value: "yes" - {{- end }} - - name: REDIS_PORT - value: {{ .Values.redisPort | quote }} - ports: - - name: redis - containerPort: {{ .Values.redisPort }} - {{- if .Values.master.livenessProbe.enabled }} - livenessProbe: - initialDelaySeconds: {{ .Values.master.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.master.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.master.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.master.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.master.livenessProbe.failureThreshold }} - exec: - command: - - sh - - -c - - /health/ping_liveness_local.sh {{ .Values.master.livenessProbe.timeoutSeconds }} - {{- end }} - {{- if .Values.master.readinessProbe.enabled}} - readinessProbe: - initialDelaySeconds: {{ .Values.master.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.master.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.master.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.master.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.master.readinessProbe.failureThreshold }} - exec: - command: - - sh - - -c - - /health/ping_readiness_local.sh {{ .Values.master.livenessProbe.timeoutSeconds }} - {{- end }} - resources: -{{ toYaml .Values.master.resources | indent 10 }} - volumeMounts: - - name: health - mountPath: /health - {{- if .Values.usePasswordFile }} - - name: redis-password - mountPath: /opt/bitnami/redis/secrets/ - {{- end }} - - name: redis-data - mountPath: {{ .Values.master.persistence.path }} - subPath: {{ .Values.master.persistence.subPath }} - - name: config - mountPath: /opt/bitnami/redis/mounted-etc - - name: redis-tmp-conf - mountPath: /opt/bitnami/redis/etc/ - {{- if and .Values.cluster.enabled .Values.sentinel.enabled }} - - name: sentinel - image: "{{ template "sentinel.image" . }}" - imagePullPolicy: {{ .Values.sentinel.image.pullPolicy | quote }} - {{- if .Values.securityContext.enabled }} - securityContext: - runAsUser: {{ .Values.securityContext.runAsUser }} - {{- end }} - command: - - /bin/bash - - -c - - | - if [[ -n $REDIS_PASSWORD_FILE ]]; then - password_aux=`cat ${REDIS_PASSWORD_FILE}` - export REDIS_PASSWORD=$password_aux - fi - if [[ ! -f /opt/bitnami/redis-sentinel/etc/sentinel.conf ]];then - cp /opt/bitnami/redis-sentinel/mounted-etc/sentinel.conf /opt/bitnami/redis-sentinel/etc/sentinel.conf - {{- if .Values.usePassword }} - printf "\nsentinel auth-pass {{ .Values.sentinel.masterSet }} $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf - {{- if .Values.sentinel.usePassword }} - printf "\nrequirepass $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf - {{- end }} - {{- end }} - {{- if .Values.sentinel.staticID }} - printf "\nsentinel myid $(echo $HOSTNAME | openssl sha1 | awk '{ print $2 }')" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf - {{- end }} - fi - echo "Getting information about current running sentinels" - # Get information from existing sentinels - existing_sentinels=$(timeout -s 9 {{ .Values.sentinel.initialCheckTimeout }} redis-cli --raw -h {{ template "redis.fullname" . }} -a "$REDIS_PASSWORD" -p {{ .Values.sentinel.service.sentinelPort }} SENTINEL sentinels {{ .Values.sentinel.masterSet }}) - echo "$existing_sentinels" | awk -f /health/parse_sentinels.awk | tee -a /opt/bitnami/redis-sentinel/etc/sentinel.conf - - redis-server /opt/bitnami/redis-sentinel/etc/sentinel.conf --sentinel - env: - {{- if .Values.usePassword }} - {{- if .Values.usePasswordFile }} - - name: REDIS_PASSWORD_FILE - value: "/opt/bitnami/redis/secrets/redis-password" - {{- else }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "redis.secretName" . }} - key: {{ template "redis.secretPasswordKey" . }} - {{- end }} - {{- else }} - - name: ALLOW_EMPTY_PASSWORD - value: "yes" - {{- end }} - - name: REDIS_SENTINEL_PORT - value: {{ .Values.sentinel.port | quote }} - ports: - - name: redis-sentinel - containerPort: {{ .Values.sentinel.port }} - {{- if .Values.sentinel.livenessProbe.enabled }} - livenessProbe: - initialDelaySeconds: {{ .Values.sentinel.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.sentinel.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.sentinel.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.sentinel.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.sentinel.livenessProbe.failureThreshold }} - exec: - command: - - sh - - -c - - /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }} - {{- end }} - {{- if .Values.sentinel.readinessProbe.enabled}} - readinessProbe: - initialDelaySeconds: {{ .Values.sentinel.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.sentinel.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.sentinel.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.sentinel.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.sentinel.readinessProbe.failureThreshold }} - exec: - command: - - sh - - -c - - /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }} - {{- end }} - resources: -{{ toYaml .Values.sentinel.resources | indent 10 }} - volumeMounts: - - name: health - mountPath: /health - {{- if .Values.usePasswordFile }} - - name: redis-password - mountPath: /opt/bitnami/redis/secrets/ - {{- end }} - - name: redis-data - mountPath: {{ .Values.master.persistence.path }} - subPath: {{ .Values.master.persistence.subPath }} - - name: config - mountPath: /opt/bitnami/redis-sentinel/mounted-etc - - name: sentinel-tmp-conf - mountPath: /opt/bitnami/redis-sentinel/etc/ - {{- end }} -{{- if .Values.metrics.enabled }} - - name: metrics - image: {{ template "redis.metrics.image" . }} - imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} - command: - - /bin/bash - - -c - - | - if [[ -f '/secrets/redis-password' ]]; then - export REDIS_PASSWORD=$(cat /secrets/redis-password) - fi - redis_exporter{{- range $key, $value := .Values.metrics.extraArgs }} --{{ $key }}={{ $value }}{{- end }} - env: - - name: REDIS_ALIAS - value: {{ template "redis.fullname" . }} - {{- if and .Values.usePassword (not .Values.usePasswordFile) }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "redis.secretName" . }} - key: {{ template "redis.secretPasswordKey" . }} - {{- end }} - volumeMounts: - {{- if .Values.usePasswordFile }} - - name: redis-password - mountPath: /secrets/ - {{- end }} - ports: - - name: metrics - containerPort: 9121 - resources: -{{ toYaml .Values.metrics.resources | indent 10 }} -{{- end }} - {{- $needsVolumePermissions := and .Values.volumePermissions.enabled (and ( and .Values.master.persistence.enabled (not .Values.persistence.existingClaim) ) .Values.securityContext.enabled) }} - {{- if or $needsVolumePermissions .Values.sysctlImage.enabled }} - initContainers: - {{- if $needsVolumePermissions }} - - name: volume-permissions - image: "{{ template "redis.volumePermissions.image" . }}" - imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} - command: ["/bin/chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }}", "{{ .Values.master.persistence.path }}"] - securityContext: - runAsUser: 0 - resources: -{{ toYaml .Values.volumePermissions.resources | indent 10 }} - volumeMounts: - - name: redis-data - mountPath: {{ .Values.master.persistence.path }} - subPath: {{ .Values.master.persistence.subPath }} - {{- end }} - {{- if .Values.sysctlImage.enabled }} - - name: init-sysctl - image: {{ template "redis.sysctl.image" . }} - imagePullPolicy: {{ default "" .Values.sysctlImage.pullPolicy | quote }} - resources: -{{ toYaml .Values.sysctlImage.resources | indent 10 }} - {{- if .Values.sysctlImage.mountHostSys }} - volumeMounts: - - name: host-sys - mountPath: /host-sys - {{- end }} - command: -{{ toYaml .Values.sysctlImage.command | indent 10 }} - securityContext: - privileged: true - runAsUser: 0 - {{- end }} - {{- end }} - volumes: - - name: health - configMap: - name: {{ template "redis.fullname" . }}-health - defaultMode: 0755 - {{- if .Values.usePasswordFile }} - - name: redis-password - secret: - secretName: {{ template "redis.secretName" . }} - items: - - key: {{ template "redis.secretPasswordKey" . }} - path: redis-password - {{- end }} - - name: config - configMap: - name: {{ template "redis.fullname" . }} - {{- if not .Values.master.persistence.enabled }} - - name: "redis-data" - emptyDir: {} - {{- else }} - {{- if .Values.persistence.existingClaim }} - - name: "redis-data" - persistentVolumeClaim: - claimName: {{ .Values.persistence.existingClaim }} - {{- end }} - {{- end }} - {{- if .Values.sysctlImage.mountHostSys }} - - name: host-sys - hostPath: - path: /sys - {{- end }} - - name: redis-tmp-conf - emptyDir: {} - {{- if and .Values.cluster.enabled .Values.sentinel.enabled }} - - name: sentinel-tmp-conf - emptyDir: {} - {{- end }} - {{- if and .Values.master.persistence.enabled (not .Values.persistence.existingClaim) }} - volumeClaimTemplates: - - metadata: - name: redis-data - labels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - component: master - spec: - accessModes: - {{- range .Values.master.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - resources: - requests: - storage: {{ .Values.master.persistence.size | quote }} - {{ include "redis.master.storageClass" . }} - selector: - {{- if .Values.master.persistence.matchLabels }} - matchLabels: -{{ toYaml .Values.master.persistence.matchLabels | indent 12 }} - {{- end -}} - {{- if .Values.master.persistence.matchExpressions }} - matchExpressions: -{{ toYaml .Values.master.persistence.matchExpressions | indent 12 }} - {{- end -}} - {{- end }} - updateStrategy: - type: {{ .Values.master.statefulset.updateStrategy }} - {{- if .Values.master.statefulset.rollingUpdatePartition }} - {{- if (eq "Recreate" .Values.master.statefulset.updateStrategy) }} - rollingUpdate: null - {{- else }} - rollingUpdate: - partition: {{ .Values.master.statefulset.rollingUpdatePartition }} - {{- end }} - {{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-master-svc.yaml b/infra/charts/feast/charts/redis/templates/redis-master-svc.yaml deleted file mode 100644 index 3a98e667f03..00000000000 --- a/infra/charts/feast/charts/redis/templates/redis-master-svc.yaml +++ /dev/null @@ -1,39 +0,0 @@ -{{- if not .Values.sentinel.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "redis.fullname" . }}-master - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - {{- if .Values.master.service.labels -}} - {{ toYaml .Values.master.service.labels | nindent 4 }} - {{- end -}} -{{- if .Values.master.service.annotations }} - annotations: {{ toYaml .Values.master.service.annotations | nindent 4 }} -{{- end }} -spec: - type: {{ .Values.master.service.type }} - {{- if and (eq .Values.master.service.type "LoadBalancer") .Values.master.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.master.service.loadBalancerIP }} - {{- end }} - {{- if and (eq .Values.master.service.type "LoadBalancer") .Values.master.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- with .Values.master.service.loadBalancerSourceRanges }} -{{ toYaml . | indent 4 }} -{{- end }} - {{- end }} - ports: - - name: redis - port: {{ .Values.master.service.port }} - targetPort: redis - {{- if .Values.master.service.nodePort }} - nodePort: {{ .Values.master.service.nodePort }} - {{- end }} - selector: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - role: master -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-role.yaml b/infra/charts/feast/charts/redis/templates/redis-role.yaml deleted file mode 100644 index 71f75ef78e6..00000000000 --- a/infra/charts/feast/charts/redis/templates/redis-role.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -rules: -{{- if .Values.podSecurityPolicy.create }} - - apiGroups: ['{{ template "podSecurityPolicy.apiGroup" . }}'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: [{{ template "redis.fullname" . }}] -{{- end -}} -{{- if .Values.rbac.role.rules }} -{{ toYaml .Values.rbac.role.rules | indent 2 }} -{{- end -}} -{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/redis-rolebinding.yaml b/infra/charts/feast/charts/redis/templates/redis-rolebinding.yaml deleted file mode 100644 index aceb258de62..00000000000 --- a/infra/charts/feast/charts/redis/templates/redis-rolebinding.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "redis.fullname" . }} -subjects: -- kind: ServiceAccount - name: {{ template "redis.serviceAccountName" . }} -{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/redis-serviceaccount.yaml b/infra/charts/feast/charts/redis/templates/redis-serviceaccount.yaml deleted file mode 100644 index f0271766006..00000000000 --- a/infra/charts/feast/charts/redis/templates/redis-serviceaccount.yaml +++ /dev/null @@ -1,11 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "redis.serviceAccountName" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -{{- end -}} diff --git a/infra/charts/feast/charts/redis/templates/redis-slave-statefulset.yaml b/infra/charts/feast/charts/redis/templates/redis-slave-statefulset.yaml deleted file mode 100755 index d5a8db56159..00000000000 --- a/infra/charts/feast/charts/redis/templates/redis-slave-statefulset.yaml +++ /dev/null @@ -1,437 +0,0 @@ -{{- if .Values.cluster.enabled }} -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ template "redis.fullname" . }}-slave - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: -{{- if .Values.slave.updateStrategy }} - strategy: -{{ toYaml .Values.slave.updateStrategy | indent 4 }} -{{- end }} - replicas: {{ .Values.cluster.slaveCount }} - serviceName: {{ template "redis.fullname" . }}-headless - selector: - matchLabels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - role: slave - template: - metadata: - labels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - chart: {{ template "redis.chart" . }} - role: slave - {{- if .Values.slave.podLabels }} -{{ toYaml .Values.slave.podLabels | indent 8 }} - {{- end }} - {{- if and .Values.metrics.enabled .Values.metrics.podLabels }} -{{ toYaml .Values.metrics.podLabels | indent 8 }} - {{- end }} - annotations: - checksum/health: {{ include (print $.Template.BasePath "/health-configmap.yaml") . | sha256sum }} - checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} - checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} - {{- if .Values.slave.podAnnotations }} -{{ toYaml .Values.slave.podAnnotations | indent 8 }} - {{- end }} - {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} -{{ toYaml .Values.metrics.podAnnotations | indent 8 }} - {{- end }} - spec: -{{- include "redis.imagePullSecrets" . | indent 6 }} - {{- if .Values.securityContext.enabled }} - securityContext: - fsGroup: {{ .Values.securityContext.fsGroup }} - {{- if .Values.securityContext.sysctls }} - sysctls: -{{ toYaml .Values.securityContext.sysctls | indent 8 }} - {{- end }} - {{- end }} - serviceAccountName: "{{ template "redis.serviceAccountName" . }}" - {{- if .Values.slave.priorityClassName }} - priorityClassName: "{{ .Values.slave.priorityClassName }}" - {{- end }} - {{- if .Values.slave.nodeSelector }} - nodeSelector: -{{ toYaml .Values.slave.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.slave.tolerations }} - tolerations: -{{ toYaml .Values.slave.tolerations | indent 8 }} - {{- end }} - {{- if .Values.slave.schedulerName }} - schedulerName: "{{ .Values.slave.schedulerName }}" - {{- end }} - {{- with .Values.slave.affinity }} - affinity: -{{ tpl (toYaml .) $ | indent 8 }} - {{- end }} - containers: - - name: {{ template "redis.fullname" . }} - image: {{ template "redis.image" . }} - imagePullPolicy: {{ .Values.image.pullPolicy | quote }} - {{- if .Values.securityContext.enabled }} - securityContext: - runAsUser: {{ .Values.securityContext.runAsUser }} - {{- end }} - command: - - /bin/bash - - -c - - | - {{- if (eq (.Values.securityContext.runAsUser | int) 0) }} - useradd redis - chown -R redis {{ .Values.slave.persistence.path }} - {{- end }} - if [[ -n $REDIS_PASSWORD_FILE ]]; then - password_aux=`cat ${REDIS_PASSWORD_FILE}` - export REDIS_PASSWORD=$password_aux - fi - if [[ -n $REDIS_MASTER_PASSWORD_FILE ]]; then - password_aux=`cat ${REDIS_MASTER_PASSWORD_FILE}` - export REDIS_MASTER_PASSWORD=$password_aux - fi - if [[ ! -f /opt/bitnami/redis/etc/replica.conf ]];then - cp /opt/bitnami/redis/mounted-etc/replica.conf /opt/bitnami/redis/etc/replica.conf - fi - if [[ ! -f /opt/bitnami/redis/etc/redis.conf ]];then - cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf - fi - ARGS=("--port" "${REDIS_PORT}") - ARGS+=("--slaveof" "${REDIS_MASTER_HOST}" "${REDIS_MASTER_PORT_NUMBER}") - {{- if .Values.usePassword }} - ARGS+=("--requirepass" "${REDIS_PASSWORD}") - ARGS+=("--masterauth" "${REDIS_MASTER_PASSWORD}") - {{- else }} - ARGS+=("--protected-mode" "no") - {{- end }} - ARGS+=("--include" "/opt/bitnami/redis/etc/redis.conf") - ARGS+=("--include" "/opt/bitnami/redis/etc/replica.conf") - {{- if .Values.slave.extraFlags }} - {{- range .Values.slave.extraFlags }} - ARGS+=({{ . | quote }}) - {{- end }} - {{- end }} - {{- if .Values.slave.command }} - {{ .Values.slave.command }} "${ARGS[@]}" - {{- else }} - redis-server "${ARGS[@]}" - {{- end }} - env: - - name: REDIS_REPLICATION_MODE - value: slave - - name: REDIS_MASTER_HOST - value: {{ template "redis.fullname" . }}-master-0.{{ template "redis.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} - - name: REDIS_PORT - value: {{ .Values.redisPort | quote }} - - name: REDIS_MASTER_PORT_NUMBER - value: {{ .Values.redisPort | quote }} - {{- if .Values.usePassword }} - {{- if .Values.usePasswordFile }} - - name: REDIS_PASSWORD_FILE - value: "/opt/bitnami/redis/secrets/redis-password" - - name: REDIS_MASTER_PASSWORD_FILE - value: "/opt/bitnami/redis/secrets/redis-password" - {{- else }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "redis.secretName" . }} - key: {{ template "redis.secretPasswordKey" . }} - - name: REDIS_MASTER_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "redis.secretName" . }} - key: {{ template "redis.secretPasswordKey" . }} - {{- end }} - {{- else }} - - name: ALLOW_EMPTY_PASSWORD - value: "yes" - {{- end }} - ports: - - name: redis - containerPort: {{ .Values.redisPort }} - {{- if .Values.slave.livenessProbe.enabled }} - livenessProbe: - initialDelaySeconds: {{ .Values.slave.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.slave.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.slave.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.slave.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.slave.livenessProbe.failureThreshold}} - exec: - command: - - sh - - -c - {{- if .Values.sentinel.enabled }} - - /health/ping_liveness_local.sh {{ .Values.slave.livenessProbe.timeoutSeconds }} - {{- else }} - - /health/ping_liveness_local_and_master.sh {{ .Values.slave.livenessProbe.timeoutSeconds }} - {{- end }} - {{- end }} - - {{- if .Values.slave.readinessProbe.enabled }} - readinessProbe: - initialDelaySeconds: {{ .Values.slave.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.slave.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.slave.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.slave.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.slave.readinessProbe.failureThreshold }} - exec: - command: - - sh - - -c - {{- if .Values.sentinel.enabled }} - - /health/ping_readiness_local.sh {{ .Values.slave.livenessProbe.timeoutSeconds }} - {{- else }} - - /health/ping_readiness_local_and_master.sh {{ .Values.slave.livenessProbe.timeoutSeconds }} - {{- end }} - {{- end }} - resources: -{{ toYaml .Values.slave.resources | indent 10 }} - volumeMounts: - - name: health - mountPath: /health - {{- if .Values.usePasswordFile }} - - name: redis-password - mountPath: /opt/bitnami/redis/secrets/ - {{- end }} - - name: redis-data - mountPath: /data - - name: config - mountPath: /opt/bitnami/redis/mounted-etc - - name: redis-tmp-conf - mountPath: /opt/bitnami/redis/etc - {{- if and .Values.cluster.enabled .Values.sentinel.enabled }} - - name: sentinel - image: "{{ template "sentinel.image" . }}" - imagePullPolicy: {{ .Values.sentinel.image.pullPolicy | quote }} - {{- if .Values.securityContext.enabled }} - securityContext: - runAsUser: {{ .Values.securityContext.runAsUser }} - {{- end }} - command: - - /bin/bash - - -c - - | - if [[ -n $REDIS_PASSWORD_FILE ]]; then - password_aux=`cat ${REDIS_PASSWORD_FILE}` - export REDIS_PASSWORD=$password_aux - fi - if [[ ! -f /opt/bitnami/redis-sentinel/etc/sentinel.conf ]];then - cp /opt/bitnami/redis-sentinel/mounted-etc/sentinel.conf /opt/bitnami/redis-sentinel/etc/sentinel.conf - {{- if .Values.usePassword }} - printf "\nsentinel auth-pass {{ .Values.sentinel.masterSet }} $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf - {{- if .Values.sentinel.usePassword }} - printf "\nrequirepass $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf - {{- end }} - {{- end }} - {{- if .Values.sentinel.staticID }} - printf "\nsentinel myid $(echo $HOSTNAME | openssl sha1 | awk '{ print $2 }')" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf - {{- end }} - fi - - redis-server /opt/bitnami/redis-sentinel/etc/sentinel.conf --sentinel - env: - {{- if .Values.usePassword }} - {{- if .Values.usePasswordFile }} - - name: REDIS_PASSWORD_FILE - value: "/opt/bitnami/redis/secrets/redis-password" - {{- else }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "redis.secretName" . }} - key: {{ template "redis.secretPasswordKey" . }} - {{- end }} - {{- else }} - - name: ALLOW_EMPTY_PASSWORD - value: "yes" - {{- end }} - - name: REDIS_SENTINEL_PORT - value: {{ .Values.sentinel.port | quote }} - ports: - - name: redis-sentinel - containerPort: {{ .Values.sentinel.port }} - {{- if .Values.sentinel.livenessProbe.enabled }} - livenessProbe: - initialDelaySeconds: {{ .Values.sentinel.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.sentinel.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.sentinel.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.sentinel.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.sentinel.livenessProbe.failureThreshold }} - exec: - command: - - sh - - -c - - /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }} - {{- end }} - {{- if .Values.sentinel.readinessProbe.enabled}} - readinessProbe: - initialDelaySeconds: {{ .Values.sentinel.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.sentinel.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.sentinel.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.sentinel.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.sentinel.readinessProbe.failureThreshold }} - exec: - command: - - sh - - -c - - /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }} - {{- end }} - resources: -{{ toYaml .Values.sentinel.resources | indent 10 }} - volumeMounts: - - name: health - mountPath: /health - {{- if .Values.usePasswordFile }} - - name: redis-password - mountPath: /opt/bitnami/redis/secrets/ - {{- end }} - - name: redis-data - mountPath: {{ .Values.master.persistence.path }} - subPath: {{ .Values.master.persistence.subPath }} - - name: config - mountPath: /opt/bitnami/redis-sentinel/mounted-etc - - name: sentinel-tmp-conf - mountPath: /opt/bitnami/redis-sentinel/etc - {{- end }} -{{- if .Values.metrics.enabled }} - - name: metrics - image: {{ template "redis.metrics.image" . }} - imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} - command: - - /bin/bash - - -c - - | - if [[ -f '/secrets/redis-password' ]]; then - export REDIS_PASSWORD=$(cat /secrets/redis-password) - fi - redis_exporter{{- range $key, $value := .Values.metrics.extraArgs }} --{{ $key }}={{ $value }}{{- end }} - env: - - name: REDIS_ALIAS - value: {{ template "redis.fullname" . }} - {{- if and .Values.usePassword (not .Values.usePasswordFile) }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "redis.secretName" . }} - key: {{ template "redis.secretPasswordKey" . }} - {{- end }} - volumeMounts: - {{- if .Values.usePasswordFile }} - - name: redis-password - mountPath: /secrets/ - {{- end }} - ports: - - name: metrics - containerPort: 9121 - resources: -{{ toYaml .Values.metrics.resources | indent 10 }} -{{- end }} - {{- $needsVolumePermissions := and .Values.volumePermissions.enabled (and .Values.slave.persistence.enabled .Values.securityContext.enabled) }} - {{- if or $needsVolumePermissions .Values.sysctlImage.enabled }} - initContainers: - {{- if $needsVolumePermissions }} - - name: volume-permissions - image: "{{ template "redis.volumePermissions.image" . }}" - imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} - command: ["/bin/chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }}", "{{ .Values.slave.persistence.path }}"] - securityContext: - runAsUser: 0 - resources: -{{ toYaml .Values.volumePermissions.resources | indent 10 }} - volumeMounts: - - name: redis-data - mountPath: {{ .Values.slave.persistence.path }} - subPath: {{ .Values.slave.persistence.subPath }} - {{- end }} - {{- if .Values.sysctlImage.enabled }} - - name: init-sysctl - image: {{ template "redis.sysctl.image" . }} - imagePullPolicy: {{ default "" .Values.sysctlImage.pullPolicy | quote }} - resources: -{{ toYaml .Values.sysctlImage.resources | indent 10 }} - {{- if .Values.sysctlImage.mountHostSys }} - volumeMounts: - - name: host-sys - mountPath: /host-sys - {{- end }} - command: -{{ toYaml .Values.sysctlImage.command | indent 10 }} - securityContext: - privileged: true - runAsUser: 0 - {{- end }} - {{- end }} - volumes: - - name: health - configMap: - name: {{ template "redis.fullname" . }}-health - defaultMode: 0755 - {{- if .Values.usePasswordFile }} - - name: redis-password - secret: - secretName: {{ template "redis.secretName" . }} - items: - - key: {{ template "redis.secretPasswordKey" . }} - path: redis-password - {{- end }} - - name: config - configMap: - name: {{ template "redis.fullname" . }} - {{- if .Values.sysctlImage.mountHostSys }} - - name: host-sys - hostPath: - path: /sys - {{- end }} - - name: sentinel-tmp-conf - emptyDir: {} - - name: redis-tmp-conf - emptyDir: {} - {{- if not .Values.slave.persistence.enabled }} - - name: redis-data - emptyDir: {} - {{- else }} - volumeClaimTemplates: - - metadata: - name: redis-data - labels: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - component: slave - spec: - accessModes: - {{- range .Values.slave.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - resources: - requests: - storage: {{ .Values.slave.persistence.size | quote }} - {{ include "redis.slave.storageClass" . }} - selector: - {{- if .Values.slave.persistence.matchLabels }} - matchLabels: -{{ toYaml .Values.slave.persistence.matchLabels | indent 12 }} - {{- end -}} - {{- if .Values.slave.persistence.matchExpressions }} - matchExpressions: -{{ toYaml .Values.slave.persistence.matchExpressions | indent 12 }} - {{- end -}} - {{- end }} - updateStrategy: - type: {{ .Values.slave.statefulset.updateStrategy }} - {{- if .Values.slave.statefulset.rollingUpdatePartition }} - {{- if (eq "Recreate" .Values.slave.statefulset.updateStrategy) }} - rollingUpdate: null - {{- else }} - rollingUpdate: - partition: {{ .Values.slave.statefulset.rollingUpdatePartition }} - {{- end }} - {{- end }} -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-slave-svc.yaml b/infra/charts/feast/charts/redis/templates/redis-slave-svc.yaml deleted file mode 100644 index 052ecea174e..00000000000 --- a/infra/charts/feast/charts/redis/templates/redis-slave-svc.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if and .Values.cluster.enabled (not .Values.sentinel.enabled) }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "redis.fullname" . }}-slave - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - {{- if .Values.slave.service.labels -}} - {{ toYaml .Values.slave.service.labels | nindent 4 }} - {{- end -}} -{{- if .Values.slave.service.annotations }} - annotations: -{{ toYaml .Values.slave.service.annotations | indent 4 }} -{{- end }} -spec: - type: {{ .Values.slave.service.type }} - {{- if and (eq .Values.slave.service.type "LoadBalancer") .Values.slave.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.slave.service.loadBalancerIP }} - {{- end }} - {{- if and (eq .Values.slave.service.type "LoadBalancer") .Values.slave.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- with .Values.slave.service.loadBalancerSourceRanges }} -{{ toYaml . | indent 4 }} -{{- end }} - {{- end }} - ports: - - name: redis - port: {{ .Values.slave.service.port }} - targetPort: redis - {{- if .Values.slave.service.nodePort }} - nodePort: {{ .Values.slave.service.nodePort }} - {{- end }} - selector: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - role: slave -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/redis-with-sentinel-svc.yaml b/infra/charts/feast/charts/redis/templates/redis-with-sentinel-svc.yaml deleted file mode 100644 index 5017c222a23..00000000000 --- a/infra/charts/feast/charts/redis/templates/redis-with-sentinel-svc.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if .Values.sentinel.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - {{- if .Values.sentinel.service.labels }} - {{ toYaml .Values.sentinel.service.labels | nindent 4 }} - {{- end }} -{{- if .Values.sentinel.service.annotations }} - annotations: -{{ toYaml .Values.sentinel.service.annotations | indent 4 }} -{{- end }} -spec: - type: {{ .Values.sentinel.service.type }} - {{ if eq .Values.sentinel.service.type "LoadBalancer" -}} {{ if .Values.sentinel.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.sentinel.service.loadBalancerIP }} - {{ end -}} - {{- end -}} - ports: - - name: redis - port: {{ .Values.sentinel.service.redisPort }} - targetPort: redis - {{- if .Values.sentinel.service.redisNodePort }} - nodePort: {{ .Values.sentinel.service.redisNodePort }} - {{- end }} - - name: redis-sentinel - port: {{ .Values.sentinel.service.sentinelPort }} - targetPort: redis-sentinel - {{- if .Values.sentinel.service.sentinelNodePort }} - nodePort: {{ .Values.sentinel.service.sentinelNodePort }} - {{- end }} - selector: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} -{{- end }} diff --git a/infra/charts/feast/charts/redis/templates/secret.yaml b/infra/charts/feast/charts/redis/templates/secret.yaml deleted file mode 100644 index ead9c611a47..00000000000 --- a/infra/charts/feast/charts/redis/templates/secret.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if and .Values.usePassword (not .Values.existingSecret) -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -type: Opaque -data: - redis-password: {{ include "redis.password" . | b64enc | quote }} -{{- end -}} diff --git a/infra/charts/feast/charts/redis/values-production.yaml b/infra/charts/feast/charts/redis/values-production.yaml deleted file mode 100644 index cae2af1ef0c..00000000000 --- a/infra/charts/feast/charts/redis/values-production.yaml +++ /dev/null @@ -1,630 +0,0 @@ -## Global Docker image parameters -## Please, note that this will override the image parameters, including dependencies, configured to use the global value -## Current available global Docker image parameters: imageRegistry and imagePullSecrets -## -global: -# imageRegistry: myRegistryName -# imagePullSecrets: -# - myRegistryKeySecretName -# storageClass: myStorageClass - redis: {} - -## Bitnami Redis image version -## ref: https://hub.docker.com/r/bitnami/redis/tags/ -## -image: - registry: docker.io - repository: bitnami/redis - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.7-debian-10-r32 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - -## String to partially override redis.fullname template (will maintain the release name) -## -# nameOverride: - -## String to fully override redis.fullname template -## -# fullnameOverride: - -## Cluster settings -cluster: - enabled: true - slaveCount: 3 - -## Use redis sentinel in the redis pod. This will disable the master and slave services and -## create one redis service with ports to the sentinel and the redis instances -sentinel: - enabled: false - ## Require password authentication on the sentinel itself - ## ref: https://redis.io/topics/sentinel - usePassword: true - ## Bitnami Redis Sentintel image version - ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ - ## - image: - registry: docker.io - repository: bitnami/redis-sentinel - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.7-debian-10-r27 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - masterSet: mymaster - initialCheckTimeout: 5 - quorum: 2 - downAfterMilliseconds: 60000 - failoverTimeout: 18000 - parallelSyncs: 1 - port: 26379 - ## Additional Redis configuration for the sentinel nodes - ## ref: https://redis.io/topics/config - ## - configmap: - ## Enable or disable static sentinel IDs for each replicas - ## If disabled each sentinel will generate a random id at startup - ## If enabled, each replicas will have a constant ID on each start-up - ## - staticID: false - ## Configure extra options for Redis Sentinel liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - ## Redis Sentinel resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Redis Sentinel Service properties - service: - ## Redis Sentinel Service type - type: ClusterIP - sentinelPort: 26379 - redisPort: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # sentinelNodePort: - # redisNodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - labels: {} - loadBalancerIP: - -## Specifies the Kubernetes Cluster's Domain Name. -## -clusterDomain: cluster.local - -networkPolicy: - ## Specifies whether a NetworkPolicy should be created - ## - enabled: true - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port Redis is listening - ## on. When true, Redis will accept connections from any source - ## (with the correct destination port). - ## - # allowExternal: true - - ## Allow connections from other namespacess. Just set label for namespace and set label for pods (optional). - ## - ingressNSMatchLabels: {} - ingressNSPodMatchLabels: {} - -serviceAccount: - ## Specifies whether a ServiceAccount should be created - ## - create: false - ## The name of the ServiceAccount to use. - ## If not set and create is true, a name is generated using the fullname template - name: - -rbac: - ## Specifies whether RBAC resources should be created - ## - create: false - - role: - ## Rules to create. It follows the role specification - # rules: - # - apiGroups: - # - extensions - # resources: - # - podsecuritypolicies - # verbs: - # - use - # resourceNames: - # - gce.unprivileged - rules: [] - -## Redis pod Security Context -securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - ## sysctl settings for master and slave pods - ## - ## Uncomment the setting below to increase the net.core.somaxconn value - ## - # sysctls: - # - name: net.core.somaxconn - # value: "10000" - -## Use password authentication -usePassword: true -## Redis password (both master and slave) -## Defaults to a random 10-character alphanumeric string if not set and usePassword is true -## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run -## -password: -## Use existing secret (ignores previous password) -# existingSecret: -## Password key to be retrieved from Redis secret -## -# existingSecretPasswordKey: - -## Mount secrets as files instead of environment variables -usePasswordFile: false - -## Persist data to a persistent volume (Redis Master) -persistence: {} - ## A manually managed Persistent Volume and Claim - ## Requires persistence.enabled: true - ## If defined, PVC must be created manually before volume will be bound - # existingClaim: - -# Redis port -redisPort: 6379 - -## -## Redis Master parameters -## -master: - ## Redis command arguments - ## - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Additional Redis configuration for the master nodes - ## ref: https://redis.io/topics/config - ## - configmap: - ## Redis additional command line flags - ## - ## Can be used to specify command line flags, for example: - ## - ## extraFlags: - ## - "--maxmemory-policy volatile-ttl" - ## - "--repl-backlog-size 1024mb" - extraFlags: [] - ## Comma-separated list of Redis commands to disable - ## - ## Can be used to disable Redis commands for security reasons. - ## Commands will be completely disabled by renaming each to an empty string. - ## ref: https://redis.io/topics/security#disabling-of-specific-commands - ## - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Master additional pod labels and annotations - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - podLabels: {} - podAnnotations: {} - - ## Redis Master resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Configure extra options for Redis Master liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - - ## Redis Master Node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - ## Redis Master pod/node affinity/anti-affinity - ## - affinity: {} - - ## Redis Master Service properties - service: - ## Redis Master Service type - type: ClusterIP - port: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - labels: {} - loadBalancerIP: - # loadBalancerSourceRanges: ["10.0.0.0/8"] - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - ## Persistent Volume selectors - ## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector - matchLabels: {} - matchExpressions: {} - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - ## Redis Master pod priorityClassName - # priorityClassName: {} - -## -## Redis Slave properties -## Note: service.type is a mandatory parameter -## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master -## -slave: - ## Slave Service properties - service: - ## Redis Slave Service type - type: ClusterIP - ## Redis port - port: 6379 - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - labels: {} - loadBalancerIP: - # loadBalancerSourceRanges: ["10.0.0.0/8"] - - ## Redis slave port - port: 6379 - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Additional Redis configuration for the slave nodes - ## ref: https://redis.io/topics/config - ## - configmap: - ## Redis extra flags - extraFlags: [] - ## List of Redis commands to disable - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Slave pod/node affinity/anti-affinity - ## - affinity: {} - - ## Configure extra options for Redis Slave liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 10 - successThreshold: 1 - failureThreshold: 5 - - ## Redis slave Resource - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - - ## Redis slave selectors and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Redis slave pod Annotation and Labels - podLabels: {} - podAnnotations: {} - - ## Redis slave pod priorityClassName - # priorityClassName: {} - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - ## Persistent Volume selectors - ## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector - matchLabels: {} - matchExpressions: {} - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - -## Prometheus Exporter / Metrics -## -metrics: - enabled: true - - image: - registry: docker.io - repository: bitnami/redis-exporter - tag: 1.4.0-debian-10-r3 - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - - ## Metrics exporter resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - # resources: {} - - ## Extra arguments for Metrics exporter, for example: - ## extraArgs: - ## check-keys: myKey,myOtherKey - # extraArgs: {} - - ## Metrics exporter pod Annotation and Labels - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "9121" - # podLabels: {} - - # Enable this if you're using https://github.com/coreos/prometheus-operator - serviceMonitor: - enabled: false - ## Specify a namespace if needed - # namespace: monitoring - # fallback to the prometheus default unless specified - # interval: 10s - ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) - ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) - ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) - selector: - prometheus: kube-prometheus - - ## Metrics exporter pod priorityClassName - # priorityClassName: {} - service: - type: ClusterIP - ## Use serviceLoadBalancerIP to request a specific static IP, - ## otherwise leave blank - # loadBalancerIP: - annotations: {} - labels: {} - - ## Custom PrometheusRule to be defined - ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart - ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions - prometheusRule: - enabled: false - additionalLabels: {} - namespace: "" - rules: [] - ## These are just examples rules, please adapt them to your needs. - ## Make sure to constraint the rules to the current postgresql service. - # - alert: RedisDown - # expr: redis_up{service="{{ template "redis.fullname" . }}-metrics"} == 0 - # for: 2m - # labels: - # severity: error - # annotations: - # summary: Redis instance {{ "{{ $instance }}" }} down - # description: Redis instance {{ "{{ $instance }}" }} is down. - # - alert: RedisMemoryHigh - # expr: > - # redis_memory_used_bytes{service="{{ template "redis.fullname" . }}-metrics"} * 100 - # / - # redis_memory_max_bytes{service="{{ template "redis.fullname" . }}-metrics"} - # > 90 =< 100 - # for: 2m - # labels: - # severity: error - # annotations: - # summary: Redis instance {{ "{{ $instance }}" }} is using too much memory - # description: Redis instance {{ "{{ $instance }}" }} is using {{ "{{ $value }}" }}% of its available memory. - # - alert: RedisKeyEviction - # expr: increase(redis_evicted_keys_total{service="{{ template "redis.fullname" . }}-metrics"}[5m]) > 0 - # for: 1s - # labels: - # severity: error - # annotations: - # summary: Redis instance {{ "{{ $instance }}" }} has evicted keys - # description: Redis instance {{ "{{ $instance }}" }} has evicted {{ "{{ $value }}" }} keys in the last 5 minutes. - -## -## Init containers parameters: -## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup -## -volumePermissions: - enabled: false - image: - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m - -## Redis config file -## ref: https://redis.io/topics/config -## -configmap: |- - # Enable AOF https://redis.io/topics/persistence#append-only-file - appendonly yes - # Disable RDB persistence, AOF persistence already enabled. - save "" - -## Sysctl InitContainer -## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) -sysctlImage: - enabled: false - command: [] - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - mountHostSys: false - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m - -## PodSecurityPolicy configuration -## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ -## -podSecurityPolicy: - ## Specifies whether a PodSecurityPolicy should be created - ## - create: false diff --git a/infra/charts/feast/charts/redis/values.schema.json b/infra/charts/feast/charts/redis/values.schema.json deleted file mode 100644 index 2138e451e42..00000000000 --- a/infra/charts/feast/charts/redis/values.schema.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema#", - "type": "object", - "properties": { - "usePassword": { - "type": "boolean", - "title": "Use password authentication", - "form": true - }, - "password": { - "type": "string", - "title": "Password", - "form": true, - "description": "Defaults to a random 10-character alphanumeric string if not set", - "hidden": { - "condition": false, - "value": "usePassword" - } - }, - "cluster": { - "type": "object", - "title": "Cluster Settings", - "form": true, - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable master-slave", - "description": "Enable master-slave architecture" - }, - "slaveCount": { - "type": "integer", - "title": "Slave Replicas", - "form": true, - "hidden": { - "condition": false, - "value": "cluster.enabled" - } - } - } - }, - "master": { - "type": "object", - "title": "Master replicas settings", - "form": true, - "properties": { - "persistence": { - "type": "object", - "title": "Persistence for master replicas", - "form": true, - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable persistence", - "description": "Enable persistence using Persistent Volume Claims" - }, - "size": { - "type": "string", - "title": "Persistent Volume Size", - "form": true, - "render": "slider", - "sliderMin": 1, - "sliderMax": 100, - "sliderUnit": "Gi", - "hidden": { - "condition": false, - "value": "master.persistence.enabled" - } - }, - "matchLabels": { - "type": "object", - "title": "Persistent Match Labels Selector" - }, - "matchExpressions": { - "type": "object", - "title": "Persistent Match Expressions Selector" - } - } - } - } - }, - "slave": { - "type": "object", - "title": "Slave replicas settings", - "form": true, - "hidden": { - "condition": false, - "value": "cluster.enabled" - }, - "properties": { - "persistence": { - "type": "object", - "title": "Persistence for slave replicas", - "form": true, - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable persistence", - "description": "Enable persistence using Persistent Volume Claims" - }, - "size": { - "type": "string", - "title": "Persistent Volume Size", - "form": true, - "render": "slider", - "sliderMin": 1, - "sliderMax": 100, - "sliderUnit": "Gi", - "hidden": { - "condition": false, - "value": "slave.persistence.enabled" - } - }, - "matchLabels": { - "type": "object", - "title": "Persistent Match Labels Selector" - }, - "matchExpressions": { - "type": "object", - "title": "Persistent Match Expressions Selector" - } - } - } - } - }, - "volumePermissions": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable Init Containers", - "description": "Use an init container to set required folder permissions on the data volume before mounting it in the final destination" - } - } - }, - "metrics": { - "type": "object", - "form": true, - "title": "Prometheus metrics details", - "properties": { - "enabled": { - "type": "boolean", - "title": "Create Prometheus metrics exporter", - "description": "Create a side-car container to expose Prometheus metrics", - "form": true - }, - "serviceMonitor": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "Create Prometheus Operator ServiceMonitor", - "description": "Create a ServiceMonitor to track metrics using Prometheus Operator", - "form": true, - "hidden": { - "condition": false, - "value": "metrics.enabled" - } - } - } - } - } - } - } -} diff --git a/infra/charts/feast/charts/redis/values.yaml b/infra/charts/feast/charts/redis/values.yaml deleted file mode 100644 index 901c5a44f9c..00000000000 --- a/infra/charts/feast/charts/redis/values.yaml +++ /dev/null @@ -1,631 +0,0 @@ -## Global Docker image parameters -## Please, note that this will override the image parameters, including dependencies, configured to use the global value -## Current available global Docker image parameters: imageRegistry and imagePullSecrets -## -global: -# imageRegistry: myRegistryName -# imagePullSecrets: -# - myRegistryKeySecretName -# storageClass: myStorageClass - redis: {} - -## Bitnami Redis image version -## ref: https://hub.docker.com/r/bitnami/redis/tags/ -## -image: - registry: docker.io - repository: bitnami/redis - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.7-debian-10-r32 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - -## String to partially override redis.fullname template (will maintain the release name) -## -# nameOverride: - -## String to fully override redis.fullname template -## -# fullnameOverride: - -## Cluster settings -cluster: - enabled: false - slaveCount: 1 - -## Use redis sentinel in the redis pod. This will disable the master and slave services and -## create one redis service with ports to the sentinel and the redis instances -sentinel: - enabled: false - ## Require password authentication on the sentinel itself - ## ref: https://redis.io/topics/sentinel - usePassword: true - ## Bitnami Redis Sentintel image version - ## ref: https://hub.docker.com/r/bitnami/redis-sentinel/tags/ - ## - image: - registry: docker.io - repository: bitnami/redis-sentinel - ## Bitnami Redis image tag - ## ref: https://github.com/bitnami/bitnami-docker-redis-sentinel#supported-tags-and-respective-dockerfile-links - ## - tag: 5.0.7-debian-10-r27 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - masterSet: mymaster - initialCheckTimeout: 5 - quorum: 2 - downAfterMilliseconds: 60000 - failoverTimeout: 18000 - parallelSyncs: 1 - port: 26379 - ## Additional Redis configuration for the sentinel nodes - ## ref: https://redis.io/topics/config - ## - configmap: - ## Enable or disable static sentinel IDs for each replicas - ## If disabled each sentinel will generate a random id at startup - ## If enabled, each replicas will have a constant ID on each start-up - ## - staticID: false - ## Configure extra options for Redis Sentinel liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - ## Redis Sentinel resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Redis Sentinel Service properties - service: - ## Redis Sentinel Service type - type: ClusterIP - sentinelPort: 26379 - redisPort: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # sentinelNodePort: - # redisNodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - labels: {} - loadBalancerIP: - -## Specifies the Kubernetes Cluster's Domain Name. -## -clusterDomain: cluster.local - -networkPolicy: - ## Specifies whether a NetworkPolicy should be created - ## - enabled: false - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port Redis is listening - ## on. When true, Redis will accept connections from any source - ## (with the correct destination port). - ## - # allowExternal: true - - ## Allow connections from other namespacess. Just set label for namespace and set label for pods (optional). - ## - ingressNSMatchLabels: {} - ingressNSPodMatchLabels: {} - -serviceAccount: - ## Specifies whether a ServiceAccount should be created - ## - create: false - ## The name of the ServiceAccount to use. - ## If not set and create is true, a name is generated using the fullname template - name: - -rbac: - ## Specifies whether RBAC resources should be created - ## - create: false - - role: - ## Rules to create. It follows the role specification - # rules: - # - apiGroups: - # - extensions - # resources: - # - podsecuritypolicies - # verbs: - # - use - # resourceNames: - # - gce.unprivileged - rules: [] - -## Redis pod Security Context -securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - ## sysctl settings for master and slave pods - ## - ## Uncomment the setting below to increase the net.core.somaxconn value - ## - # sysctls: - # - name: net.core.somaxconn - # value: "10000" - -## Use password authentication -usePassword: false -## Redis password (both master and slave) -## Defaults to a random 10-character alphanumeric string if not set and usePassword is true -## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run -## -password: "" -## Use existing secret (ignores previous password) -# existingSecret: -## Password key to be retrieved from Redis secret -## -# existingSecretPasswordKey: - -## Mount secrets as files instead of environment variables -usePasswordFile: false - -## Persist data to a persistent volume (Redis Master) -persistence: {} - ## A manually managed Persistent Volume and Claim - ## Requires persistence.enabled: true - ## If defined, PVC must be created manually before volume will be bound - # existingClaim: - -# Redis port -redisPort: 6379 - -## -## Redis Master parameters -## -master: - ## Redis command arguments - ## - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Additional Redis configuration for the master nodes - ## ref: https://redis.io/topics/config - ## - configmap: - ## Redis additional command line flags - ## - ## Can be used to specify command line flags, for example: - ## - ## extraFlags: - ## - "--maxmemory-policy volatile-ttl" - ## - "--repl-backlog-size 1024mb" - extraFlags: [] - ## Comma-separated list of Redis commands to disable - ## - ## Can be used to disable Redis commands for security reasons. - ## Commands will be completely disabled by renaming each to an empty string. - ## ref: https://redis.io/topics/security#disabling-of-specific-commands - ## - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Master additional pod labels and annotations - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - podLabels: {} - podAnnotations: {} - - ## Redis Master resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Configure extra options for Redis Master liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - - ## Redis Master Node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - ## - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - ## Redis Master pod/node affinity/anti-affinity - ## - affinity: {} - - ## Redis Master Service properties - service: - ## Redis Master Service type - type: ClusterIP - port: 6379 - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - labels: {} - loadBalancerIP: - # loadBalancerSourceRanges: ["10.0.0.0/8"] - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - ## Persistent Volume selectors - ## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector - matchLabels: {} - matchExpressions: {} - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - ## Redis Master pod priorityClassName - # priorityClassName: {} - -## -## Redis Slave properties -## Note: service.type is a mandatory parameter -## The rest of the parameters are either optional or, if undefined, will inherit those declared in Redis Master -## -slave: - ## Slave Service properties - service: - ## Redis Slave Service type - type: ClusterIP - ## Redis port - port: 6379 - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - labels: {} - loadBalancerIP: - # loadBalancerSourceRanges: ["10.0.0.0/8"] - - ## Redis slave port - port: 6379 - ## Can be used to specify command line arguments, for example: - ## - command: "/run.sh" - ## Additional Redis configuration for the slave nodes - ## ref: https://redis.io/topics/config - ## - configmap: - ## Redis extra flags - extraFlags: [] - ## List of Redis commands to disable - disableCommands: - - FLUSHDB - - FLUSHALL - - ## Redis Slave pod/node affinity/anti-affinity - ## - affinity: {} - - ## Configure extra options for Redis Slave liveness and readiness probes - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) - ## - livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 10 - successThreshold: 1 - failureThreshold: 5 - - ## Redis slave Resource - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - - ## Redis slave selectors and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Redis slave pod Annotation and Labels - podLabels: {} - podAnnotations: {} - - ## Redis slave pod priorityClassName - # priorityClassName: {} - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - persistence: - enabled: true - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /data - ## The subdirectory of the volume to mount to, useful in dev environments - ## and one PV for multiple services. - subPath: "" - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - ## Persistent Volume selectors - ## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector - matchLabels: {} - matchExpressions: {} - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: RollingUpdate - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - -## Prometheus Exporter / Metrics -## -metrics: - enabled: false - - image: - registry: docker.io - repository: bitnami/redis-exporter - tag: 1.4.0-debian-10-r3 - 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - - ## Metrics exporter resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - # resources: {} - - ## Extra arguments for Metrics exporter, for example: - ## extraArgs: - ## check-keys: myKey,myOtherKey - # extraArgs: {} - - ## Metrics exporter pod Annotation and Labels - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "9121" - # podLabels: {} - - # Enable this if you're using https://github.com/coreos/prometheus-operator - serviceMonitor: - enabled: false - ## Specify a namespace if needed - # namespace: monitoring - # fallback to the prometheus default unless specified - # interval: 10s - ## Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr) - ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1) - ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters) - selector: - prometheus: kube-prometheus - - ## Custom PrometheusRule to be defined - ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart - ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions - prometheusRule: - enabled: false - additionalLabels: {} - namespace: "" - rules: [] - ## These are just examples rules, please adapt them to your needs. - ## Make sure to constraint the rules to the current postgresql service. - # - alert: RedisDown - # expr: redis_up{service="{{ template "redis.fullname" . }}-metrics"} == 0 - # for: 2m - # labels: - # severity: error - # annotations: - # summary: Redis instance {{ "{{ $instance }}" }} down - # description: Redis instance {{ "{{ $instance }}" }} is down. - # - alert: RedisMemoryHigh - # expr: > - # redis_memory_used_bytes{service="{{ template "redis.fullname" . }}-metrics"} * 100 - # / - # redis_memory_max_bytes{service="{{ template "redis.fullname" . }}-metrics"} - # > 90 =< 100 - # for: 2m - # labels: - # severity: error - # annotations: - # summary: Redis instance {{ "{{ $instance }}" }} is using too much memory - # description: Redis instance {{ "{{ $instance }}" }} is using {{ "{{ $value }}" }}% of its available memory. - # - alert: RedisKeyEviction - # expr: increase(redis_evicted_keys_total{service="{{ template "redis.fullname" . }}-metrics"}[5m]) > 0 - # for: 1s - # labels: - # severity: error - # annotations: - # summary: Redis instance {{ "{{ $instance }}" }} has evicted keys - # description: Redis instance {{ "{{ $instance }}" }} has evicted {{ "{{ $value }}" }} keys in the last 5 minutes. - - - ## Metrics exporter pod priorityClassName - # priorityClassName: {} - service: - type: ClusterIP - ## Use serviceLoadBalancerIP to request a specific static IP, - ## otherwise leave blank - # loadBalancerIP: - annotations: {} - labels: {} - -## -## Init containers parameters: -## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup -## -volumePermissions: - enabled: false - image: - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m - -## Redis config file -## ref: https://redis.io/topics/config -## -configmap: |- - # Enable AOF https://redis.io/topics/persistence#append-only-file - appendonly yes - # Disable RDB persistence, AOF persistence already enabled. - save "" - -## Sysctl InitContainer -## used to perform sysctl operation to modify Kernel settings (needed sometimes to avoid warnings) -sysctlImage: - enabled: false - command: [] - registry: docker.io - repository: bitnami/minideb - tag: buster - pullPolicy: Always - ## 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/ - ## - # pullSecrets: - # - myRegistryKeySecretName - mountHostSys: false - resources: {} - # resources: - # requests: - # memory: 128Mi - # cpu: 100m - -## PodSecurityPolicy configuration -## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ -## -podSecurityPolicy: - ## Specifies whether a PodSecurityPolicy should be created - ## - create: false diff --git a/infra/charts/feast/requirements.lock b/infra/charts/feast/requirements.lock new file mode 100644 index 00000000000..c6ff995bacc --- /dev/null +++ b/infra/charts/feast/requirements.lock @@ -0,0 +1,30 @@ +dependencies: +- name: feast-core + repository: "" + version: 0.5.0-alpha.1 +- name: feast-serving + repository: "" + version: 0.5.0-alpha.1 +- name: feast-serving + repository: "" + version: 0.5.0-alpha.1 +- name: postgresql + repository: https://kubernetes-charts.storage.googleapis.com/ + version: 8.6.1 +- name: kafka + repository: https://kubernetes-charts-incubator.storage.googleapis.com/ + version: 0.20.8 +- name: redis + repository: https://kubernetes-charts.storage.googleapis.com/ + version: 10.5.6 +- name: prometheus-statsd-exporter + repository: "" + version: 0.1.2 +- name: prometheus + repository: https://kubernetes-charts.storage.googleapis.com/ + version: 11.0.2 +- name: grafana + repository: https://kubernetes-charts.storage.googleapis.com/ + version: 5.0.5 +digest: sha256:e325439384ef9b45428fbeafe8f1e230b331d4b5482c3f26f07b71cecae06c22 +generated: "2020-05-02T15:00:45.4365217+08:00" diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index 48fcaf09ee6..7de78705752 100644 --- a/infra/charts/feast/requirements.yaml +++ b/infra/charts/feast/requirements.yaml @@ -12,19 +12,24 @@ dependencies: condition: feast-batch-serving.enabled - name: postgresql version: 8.6.1 + repository: https://kubernetes-charts.storage.googleapis.com/ condition: postgresql.enabled - name: kafka version: 0.20.8 + repository: https://kubernetes-charts-incubator.storage.googleapis.com/ condition: kafka.enabled - name: redis version: 10.5.6 + repository: https://kubernetes-charts.storage.googleapis.com/ condition: redis.enabled - name: prometheus-statsd-exporter version: 0.1.2 condition: prometheus-statsd-exporter.enabled - name: prometheus version: 11.0.2 + repository: https://kubernetes-charts.storage.googleapis.com/ condition: prometheus.enabled - name: grafana version: 5.0.5 + repository: https://kubernetes-charts.storage.googleapis.com/ condition: grafana.enabled From 24c30d6e34a71c43065e98ecd0fe10a27fbe8932 Mon Sep 17 00:00:00 2001 From: David Heryanto Date: Sat, 2 May 2020 20:02:26 +0800 Subject: [PATCH 15/15] Update example values so it's compatible with Feast v0.5. Add helm documentation for .Values.gcpProjectId --- .../charts/feast/charts/feast-core/README.md | 1 + .../feast/charts/feast-core/values.yaml | 3 + .../feast/charts/feast-serving/README.md | 1 + .../feast/charts/feast-serving/values.yaml | 3 + infra/charts/feast/values-batch-serving.yaml | 35 +++++--- .../charts/feast/values-dataflow-runner.yaml | 87 +++++++++++-------- .../charts/feast/values-existing-secret.yaml | 10 --- 7 files changed, 79 insertions(+), 61 deletions(-) delete mode 100644 infra/charts/feast/values-existing-secret.yaml diff --git a/infra/charts/feast/charts/feast-core/README.md b/infra/charts/feast/charts/feast-core/README.md index 7c033090b9c..4bf4578eb75 100644 --- a/infra/charts/feast/charts/feast-core/README.md +++ b/infra/charts/feast/charts/feast-core/README.md @@ -17,6 +17,7 @@ Current chart version is `0.5.0-alpha.1` | "application-secret.yaml" | object | `{"enabled":true}` | Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify config management. | | "application.yaml".enabled | bool | `true` | Flag to include the default [configuration](https://github.com/gojek/feast/blob/master/core/src/main/resources/application.yml). Please set `application-override.yaml` to override this configuration. | | envOverrides | object | `{}` | Extra environment variables to set | +| gcpProjectId | string | `""` | Project ID to use when using Google Cloud services such as BigQuery, Cloud Storage and Dataflow | | gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | | gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | | gcpServiceAccount.existingSecret.name | string | `"feast-gcp-service-account"` | Name of the existing secret containing the service account | diff --git a/infra/charts/feast/charts/feast-core/values.yaml b/infra/charts/feast/charts/feast-core/values.yaml index 28b5a952d54..5032e8d87ae 100644 --- a/infra/charts/feast/charts/feast-core/values.yaml +++ b/infra/charts/feast/charts/feast-core/values.yaml @@ -38,6 +38,9 @@ postgresql: # postgresql.existingSecret -- Existing secret to use for authenticating to Postgres existingSecret: "" +# gcpProjectId -- Project ID to use when using Google Cloud services such as BigQuery, Cloud Storage and Dataflow +gcpProjectId: "" + # javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). For better performance, it is advised to set the min and max heap:
`-Xms2048m -Xmx2048m` javaOpts: diff --git a/infra/charts/feast/charts/feast-serving/README.md b/infra/charts/feast/charts/feast-serving/README.md index df64b56aa42..7882463977a 100644 --- a/infra/charts/feast/charts/feast-serving/README.md +++ b/infra/charts/feast/charts/feast-serving/README.md @@ -17,6 +17,7 @@ Current chart version is `0.5.0-alpha.1` | "application-secret.yaml" | object | `{"enabled":true}` | Configuration to override the default [application.yaml](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Will be created as a Secret. `application-override.yaml` has a higher precedence than `application-secret.yaml`. It is recommended to either set `application-override.yaml` or `application-secret.yaml` only to simplify config management. | | "application.yaml".enabled | bool | `true` | Flag to include the default [configuration](https://github.com/gojek/feast/blob/master/serving/src/main/resources/application.yml). Please set `application-override.yaml` to override this configuration. | | envOverrides | object | `{}` | Extra environment variables to set | +| gcpProjectId | string | `""` | Project ID to use when using Google Cloud services such as BigQuery, Cloud Storage and Dataflow | | gcpServiceAccount.enabled | bool | `false` | Flag to use [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) JSON key | | gcpServiceAccount.existingSecret.key | string | `"credentials.json"` | Key in the secret data (file name of the service account) | | gcpServiceAccount.existingSecret.name | string | `"feast-gcp-service-account"` | Name of the existing secret containing the service account | diff --git a/infra/charts/feast/charts/feast-serving/values.yaml b/infra/charts/feast/charts/feast-serving/values.yaml index 1eb0fcb1fa7..bf7b2c772a6 100644 --- a/infra/charts/feast/charts/feast-serving/values.yaml +++ b/infra/charts/feast/charts/feast-serving/values.yaml @@ -35,6 +35,9 @@ gcpServiceAccount: # gcpServiceAccount.existingSecret.key -- Key in the secret data (file name of the service account) key: credentials.json +# gcpProjectId -- Project ID to use when using Google Cloud services such as BigQuery, Cloud Storage and Dataflow +gcpProjectId: "" + # javaOpts -- [JVM options](https://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html). For better performance, it is advised to set the min and max heap:
`-Xms2048m -Xmx2048m` javaOpts: diff --git a/infra/charts/feast/values-batch-serving.yaml b/infra/charts/feast/values-batch-serving.yaml index 1e50523ccca..7c28dc3f13e 100644 --- a/infra/charts/feast/values-batch-serving.yaml +++ b/infra/charts/feast/values-batch-serving.yaml @@ -1,22 +1,29 @@ feast-core: gcpServiceAccount: enabled: true + postgresql: + existingSecret: feast-postgresql feast-batch-serving: enabled: true - store.yaml: - name: bigquery-store - type: BIGQUERY - bigquery_config: - project_id: - dataset_id: - subscriptions: - - project: "*" - name: "*" - version: "*" - application-override.yaml: - feast: - jobs: - staging-location: gs:///staging-location gcpServiceAccount: enabled: true + application-override.yaml: + feast: + active_store: historical + stores: + - name: historical + type: BIGQUERY + config: + project_id: + dataset_id: + staging_location: gs:///feast-staging-location + initial_retry_delay_seconds: 3 + total_timeout_seconds: 21600 + subscriptions: + - name: "*" + project: "*" + version: "*" + +postgresql: + existingSecret: feast-postgresql diff --git a/infra/charts/feast/values-dataflow-runner.yaml b/infra/charts/feast/values-dataflow-runner.yaml index 3cdf5cc78ed..0469a6349e2 100644 --- a/infra/charts/feast/values-dataflow-runner.yaml +++ b/infra/charts/feast/values-dataflow-runner.yaml @@ -1,58 +1,71 @@ +# values-dataflow-runner.yaml feast-core: gcpServiceAccount: enabled: true + postgresql: + existingSecret: feast-postgresql application-override.yaml: feast: stream: options: bootstrapServers: jobs: - runner: DataflowRunner - options: - project: - region: - zone: - tempLocation: - network: - subnetwork: - maxNumWorkers: 1 - autoscalingAlgorithm: THROUGHPUT_BASED - usePublicIps: false - workerMachineType: n1-standard-1 - deadLetterTableSpec: + active_runner: dataflow metrics: host: + runners: + - name: dataflow + type: DataflowRunner + options: + project: + region: + zone: + tempLocation: + network: + subnetwork: + maxNumWorkers: 1 + autoscalingAlgorithm: THROUGHPUT_BASED + usePublicIps: false + workerMachineType: n1-standard-1 + deadLetterTableSpec: feast-online-serving: - store.yaml: - name: redis-store - type: REDIS - redis_config: - host: - port: 6379 - subscriptions: - - project: "*" - name: "*" - version: "*" + application-override.yaml: + feast: + stores: + - name: online + type: REDIS + config: + host: + port: 6379 + subscriptions: + - name: "*" + project: "*" + version: "*" feast-batch-serving: enabled: true - store.yaml: - name: bigquery-store - type: BIGQUERY - bigquery_config: - project_id: - dataset_id: - subscriptions: - - project: "*" - name: "*" - version: "*" - application-override.yaml: - feast: - jobs: - staging-location: gcpServiceAccount: enabled: true + application-override.yaml: + feast: + active_store: historical + stores: + - name: historical + type: BIGQUERY + config: + project_id: + dataset_id: + staging_location: gs:///feast-staging-location + initial_retry_delay_seconds: 3 + total_timeout_seconds: 21600 + subscriptions: + - name: "*" + project: "*" + version: "*" + +postgresql: + existingSecret: feast-postgresql kafka: external: diff --git a/infra/charts/feast/values-existing-secret.yaml b/infra/charts/feast/values-existing-secret.yaml deleted file mode 100644 index 0cccf004db9..00000000000 --- a/infra/charts/feast/values-existing-secret.yaml +++ /dev/null @@ -1,10 +0,0 @@ -feast-core: - postgresql: - existingSecret: feast-postgresql - -postgresql: - existingSecret: feast-postgresql - -grafana: - admin: - existingSecret: feast-grafana