From 69f875fdc6bd3b2bb4bdd0541c5d4ba9bf855eaf Mon Sep 17 00:00:00 2001 From: atarasov Date: Wed, 18 Jun 2025 16:56:14 +0300 Subject: [PATCH 1/3] CON-34562 - add `ocean-right-sizing-controller` Helm chart --- .../ocean-right-sizing-controller/.helmignore | 23 ++ .../ocean-right-sizing-controller/Chart.lock | 9 + .../ocean-right-sizing-controller/Chart.yaml | 25 ++ .../ocean-right-sizing-controller/README.md | 161 ++++++++ .../README.md.gotmpl | 64 ++++ .../charts/metrics-server-3.12.2.tgz | Bin 0 -> 10395 bytes .../charts/ocean-vpa-1.0.4.tgz | Bin 0 -> 11060 bytes .../templates/_helpers.tpl | 351 ++++++++++++++++++ .../templates/auto-update/_job.yaml | 85 +++++ .../templates/auto-update/clusterrole.yaml | 53 +++ .../auto-update/clusterrolebinding.yaml | 16 + .../templates/auto-update/role.yaml | 82 ++++ .../templates/auto-update/rolebinding.yaml | 15 + .../templates/auto-update/serviceaccount.yaml | 14 + .../templates/caBundle.secret.yaml | 11 + .../templates/clusterrole.yaml | 65 ++++ .../templates/clusterrolebinding.yaml | 14 + .../templates/configmap.yaml | 109 ++++++ .../templates/deployment.yaml | 263 +++++++++++++ .../templates/resourcequota.yaml | 19 + .../templates/role.yaml | 14 + .../templates/rolebinding.yaml | 15 + .../templates/secret.yaml | 12 + .../templates/serviceaccount.yaml | 12 + .../ocean-right-sizing-controller/values.yaml | 301 +++++++++++++++ 25 files changed, 1733 insertions(+) create mode 100644 charts/ocean-right-sizing-controller/.helmignore create mode 100644 charts/ocean-right-sizing-controller/Chart.lock create mode 100644 charts/ocean-right-sizing-controller/Chart.yaml create mode 100644 charts/ocean-right-sizing-controller/README.md create mode 100644 charts/ocean-right-sizing-controller/README.md.gotmpl create mode 100644 charts/ocean-right-sizing-controller/charts/metrics-server-3.12.2.tgz create mode 100644 charts/ocean-right-sizing-controller/charts/ocean-vpa-1.0.4.tgz create mode 100644 charts/ocean-right-sizing-controller/templates/_helpers.tpl create mode 100644 charts/ocean-right-sizing-controller/templates/auto-update/_job.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/auto-update/clusterrole.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/auto-update/clusterrolebinding.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/auto-update/role.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/auto-update/rolebinding.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/auto-update/serviceaccount.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/caBundle.secret.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/clusterrole.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/clusterrolebinding.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/configmap.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/deployment.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/resourcequota.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/role.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/rolebinding.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/secret.yaml create mode 100644 charts/ocean-right-sizing-controller/templates/serviceaccount.yaml create mode 100644 charts/ocean-right-sizing-controller/values.yaml diff --git a/charts/ocean-right-sizing-controller/.helmignore b/charts/ocean-right-sizing-controller/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/ocean-right-sizing-controller/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/ocean-right-sizing-controller/Chart.lock b/charts/ocean-right-sizing-controller/Chart.lock new file mode 100644 index 00000000..85cfb595 --- /dev/null +++ b/charts/ocean-right-sizing-controller/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: metrics-server + repository: https://kubernetes-sigs.github.io/metrics-server + version: 3.12.2 +- name: ocean-vpa + repository: https://charts.spot.io + version: 1.0.4 +digest: sha256:bc126e327103cb3506c42e0d91a4771cb1824160669c3579604e06f5c0760f6a +generated: "2025-06-18T11:39:19.608047+03:00" diff --git a/charts/ocean-right-sizing-controller/Chart.yaml b/charts/ocean-right-sizing-controller/Chart.yaml new file mode 100644 index 00000000..bb1ccf73 --- /dev/null +++ b/charts/ocean-right-sizing-controller/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +name: ocean-right-sizing-controller +description: A Helm chart for Ocean Right-Sizing Controller +type: application +version: 0.1.62 +appVersion: 2.0.70 +kubeVersion: ">=1.20.0-0" +maintainers: + - name: spotinst + email: ng-spot-info@netapp.com +icon: https://docs.spot.io/_media/images/spot_mark.png +keywords: + - spot + - ocean + - right-sizing + - controller +dependencies: + - name: metrics-server + version: 3.12.2 + repository: https://kubernetes-sigs.github.io/metrics-server + condition: metrics-server.deployChart + - name: ocean-vpa + version: 1.0.4 + repository: https://charts.spot.io + condition: ocean-vpa.deployChart diff --git a/charts/ocean-right-sizing-controller/README.md b/charts/ocean-right-sizing-controller/README.md new file mode 100644 index 00000000..e8f6619a --- /dev/null +++ b/charts/ocean-right-sizing-controller/README.md @@ -0,0 +1,161 @@ +# ocean-right-sizing-controller + +![Version: 0.1.62](https://img.shields.io/badge/Version-0.1.62-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.0.70](https://img.shields.io/badge/AppVersion-2.0.70-informational?style=flat-square) + +A Helm chart for Ocean Right-Sizing Controller. + +## Installation + +1. Add the Spot Helm chart repository: + +```sh +helm repo add spot https://charts.spot.io +``` + +2. Update your local Helm chart repository cache: + +```sh +helm repo update +``` + +3. Install `ocean-right-sizing-controller`: + +```sh +helm install spot spot/ocean-right-sizing-controller \ + --set spotinst.account=$SPOTINST_ACCOUNT \ + --set spotinst.clusterIdentifier=$SPOTINST_CLUSTER_IDENTIFIER \ + --set spotinst.token=$SPOTINST_TOKEN +``` + +> NOTE: Please configure all required chart values using the `set` command line argument or a `values.yaml` file. + +## Installation With HTTPS Proxy + +In case you need to configure a proxy with a custom CA bundle you should use the following: + +```sh +helm install spot spot/ocean-right-sizing-controller \ + --set spotinst.account=$SPOTINST_ACCOUNT \ + --set spotinst.clusterIdentifier=$SPOTINST_CLUSTER_IDENTIFIER \ + --set spotinst.token=$SPOTINST_TOKEN \ + --set spotinst.proxyUrl=$SPOTINST_PROXY_URL \ + --set caBundleSecret.create=true \ + --set caBundleSecret.data="$(cat ./path/to/ca.pem)" +``` + +If you already have a CA bundle secret you can instead use: + +```sh +helm install spot spot/ocean-right-sizing-controller \ + --set spotinst.account=$SPOTINST_ACCOUNT \ + --set spotinst.clusterIdentifier=$SPOTINST_CLUSTER_IDENTIFIER \ + --set spotinst.token=$SPOTINST_TOKEN \ + --set spotinst.proxyUrl=$SPOTINST_PROXY_URL \ + --set caBundleSecret.name=my-ca-bundle-secret \ + --set caBundleSecret.key=bundle.pem +``` + +## Requirements + +Kubernetes: `>=1.20.0-0` + +| Repository | Name | Version | +|--------------------------------------------------|----------------|---------| +| https://charts.spot.io | ocean-vpa | 1.0.4 | +| https://kubernetes-sigs.github.io/metrics-server | metrics-server | 3.12.2 | + +## Values + +| Key | Type | Default | Description | +|------------------------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| affinity | string | `nil` | | +| args | list | `[]` | | +| autoUpdate.image | object | `{"pullPolicy":"Always","repository":"us-docker.pkg.dev/spotit-today/container-labs/auto-updater","tag":"latest"}` | Configures the image for the auto-updater job. (Optional) | +| autoUpdate.image.pullPolicy | string | `"Always"` | Image pull policy. (Optional) | +| autoUpdate.image.repository | string | `"us-docker.pkg.dev/spotit-today/container-labs/auto-updater"` | Image repository. (Optional) | +| autoUpdate.image.tag | string | `"latest"` | Overrides the image tag. (Optional) | +| autoUpdate.imagePullSecrets | list | `[]` | Image pull secrets. (Optional) | +| autoUpdate.podSecurityContext | object | `{"fsGroup":1000690000,"runAsGroup":1000690000,"runAsNonRoot":true,"runAsUser":1000690000}` | Pod Security Context for the auto-updater job. (Optional) Ref: https://kubernetes.io/docs/concepts/security/pod-security-standards/ | +| autoUpdate.priorityClassName | string | `"system-cluster-critical"` | Priority class name for the auto-updater job. Defaults to the same priority class as the controller to prevent eviction. (Optional) | +| autoUpdate.resources | object | `{"limits":{"cpu":"100m","memory":"256Mi"},"requests":{"cpu":"100m","memory":"256Mi"}}` | Resource requests and limits for the auto-updater job. Defaults to 100m CPU and 256Mi memory to make the job run with 'Guranteed' QoS. (Optional) | +| autoUpdate.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}` | Security Context for the auto-updater container. (Optional) | +| autoUpdate.serviceAccount.annotations | object | `{}` | | +| autoUpdate.serviceAccount.create | bool | `true` | | +| autoUpdate.serviceAccount.name | string | `""` | | +| caBundleSecret.create | bool | `false` | Controls whether a CA bundle secret should be created. | +| caBundleSecret.data | string | `""` | Must contain the CA bundle data in case `caBundleSecret.create` is true. For example by using `--set caBundleSecret.data="$(cat ./ca.pem)"` | +| caBundleSecret.key | string | `"userEnvCertificates.pem"` | Key inside the secret to inject the CA bundle from | +| caBundleSecret.name | string | `""` | CA bundle Secret name. (Optional) | +| command | list | `[]` | | +| commonLabels | object | `{}` | | +| configMap.create | bool | `true` | | +| configMap.name | string | `""` | ConfigMap name. (Optional) | +| deploymentAnnotations | object | `{}` | | +| extraEnv | list | `[]` | | +| extraVolumeMounts | list | `[]` | | +| extraVolumes | list | `[]` | | +| fullnameOverride | string | `""` | | +| image.fips | bool | `false` | Set to `true` to use an FIPS-140 compliant image. This flag adds `-fips` suffix to the image tag, therefore it should not be used together with the `--image.tag` flag. Ref: https://go.dev/doc/security/fips140 | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"us-docker.pkg.dev/spotit-today/container-labs/spotinst-kubernetes-controller"` | | +| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | +| imagePullSecrets | list | `[]` | | +| initContainers | list | `[]` | | +| livenessProbe.httpGet.path | string | `"/healthz"` | | +| livenessProbe.httpGet.port | string | `"readiness"` | | +| livenessProbe.initialDelaySeconds | int | `15` | | +| livenessProbe.periodSeconds | int | `20` | | +| logShipping | object | `{"command":["/fluent-bit/bin/fluent-bit","-c","/tmp/fluent-bit.conf","-q"],"destination":{"host":"api.spotinst.io","port":443,"tls":true},"enabled":true,"extraEnv":[],"extraVolumeMounts":[],"image":{"pullPolicy":"IfNotPresent","repository":"ghcr.io/fluent/fluent-bit","tag":"3.1.9"},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}}` | Log Shipping configuration. | +| logShipping.command | list | `["/fluent-bit/bin/fluent-bit","-c","/tmp/fluent-bit.conf","-q"]` | Log shipping container command. (Optional) | +| logShipping.destination | object | `{"host":"api.spotinst.io","port":443,"tls":true}` | Log shipping destination configuration. | +| logShipping.enabled | bool | `true` | Specifies whether to send the controller logs to Spot for analysis. (Optional) | +| logShipping.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. (Optional) | +| logShipping.image.repository | string | `"ghcr.io/fluent/fluent-bit"` | Image repository. (Optional) | +| logShipping.image.tag | string | `"3.1.9"` | Overrides the image tag. (Optional) | +| logShipping.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}` | Log Shipping container security context | +| metrics-server.deployChart | bool | `true` | Specifies whether the metrics-server chart should be deployed. | +| metrics-server.image.pullPolicy | string | `"IfNotPresent"` | | +| metrics-server.image.repository | string | `"registry.k8s.io/metrics-server/metrics-server"` | | +| metrics-server.image.tag | string | `""` | | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| ocean-vpa.deployChart | bool | `true` | Specifies whether the ocean-vpa chart should be deployed. | +| podAnnotations | object | `{}` | | +| podLabels | object | `{}` | | +| podSecurityContext.fsGroup | int | `1000690000` | | +| podSecurityContext.runAsGroup | int | `1000690000` | | +| podSecurityContext.runAsNonRoot | bool | `true` | | +| podSecurityContext.runAsUser | int | `1000690000` | | +| priorityClassName | string | `"system-node-critical"` | Priority class name for the controller pod. | +| readinessProbe.httpGet.path | string | `"/readyz"` | | +| readinessProbe.httpGet.port | string | `"readiness"` | | +| readinessProbe.initialDelaySeconds | int | `5` | | +| readinessProbe.periodSeconds | int | `10` | | +| replicas | int | `2` | Configure the amount of replicas for the controller (Optional) | +| resourceQuota | object | `{"enabled":true}` | Resource Quota configuration. Required when running in a namespace other than kube-system in GKE. Ref: https://kubernetes.io/docs/concepts/policy/resource-quotas/ | +| resources | object | `{}` | | +| schedulerName | string | `""` | | +| secret.create | bool | `true` | Controls whether a Secret should be created. (Optional) | +| secret.name | string | `""` | Secret name. (Optional) | +| securityContext.allowPrivilegeEscalation | bool | `false` | | +| securityContext.capabilities.drop[0] | string | `"ALL"` | | +| securityContext.readOnlyRootFilesystem | bool | `true` | | +| securityContext.runAsNonRoot | bool | `true` | | +| serviceAccount.annotations | object | `{}` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `""` | | +| spotinst.account | string | `""` | Spot Account ID. (Required) Example: `act-123abcd` | +| spotinst.baseUrl | string | `""` | Base URL. (Optional) | +| spotinst.clusterIdentifier | string | `""` | Unique identifier used by the Ocean Controller to connect (Required) between the Ocean backend and the Kubernetes cluster. Ref: https://docs.spot.io/ocean/tutorials/spot-kubernetes-controller/ | +| spotinst.disableAutoUpdate | bool | `false` | Disable auto update. (Optional) | +| spotinst.enableCsrApproval | bool | `true` | Enable CSR approval. (Optional) | +| spotinst.insecureSkipTLSVerify | bool | `false` | Disable TLS certificate validation. (Optional) | +| spotinst.proxyUrl | string | `""` | Proxy URL. (Optional) | +| spotinst.readonly | bool | `true` | Whether this controller needs to be readonly - overrides other permissions. (Optional) | +| spotinst.token | string | `""` | Spot Token. (Required) Ref: https://docs.spot.io/administration/api/create-api-token | +| tolerations | string | `nil` | Tolerations for nodes that have taints on them. (Optional) Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | +| topologySpreadConstraints | string | `nil` | | +| updateStrategy | object | `{}` | | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/charts/ocean-right-sizing-controller/README.md.gotmpl b/charts/ocean-right-sizing-controller/README.md.gotmpl new file mode 100644 index 00000000..1ddff9c2 --- /dev/null +++ b/charts/ocean-right-sizing-controller/README.md.gotmpl @@ -0,0 +1,64 @@ +{{ template "chart.header" . }} + +{{ template "chart.deprecationWarning" . }} + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +{{ template "chart.description" . }}. + +## Installation + +1. Add the Spot Helm chart repository: + +```sh +helm repo add spot https://charts.spot.io +``` + +2. Update your local Helm chart repository cache: + +```sh +helm repo update +``` + +3. Install `{{ template "chart.name" . }}`: + +```sh +helm install spot spot/{{ template "chart.name" . }} \ + --set spotinst.account=$SPOTINST_ACCOUNT \ + --set spotinst.clusterIdentifier=$SPOTINST_CLUSTER_IDENTIFIER \ + --set spotinst.token=$SPOTINST_TOKEN +``` + +> NOTE: Please configure all required chart values using the `set` command line argument or a `values.yaml` file. + +## Installation With HTTPS Proxy + +In case you need to configure a proxy with a custom CA bundle you should use the following: + +```sh +helm install spot spot/{{ template "chart.name" . }} \ + --set spotinst.account=$SPOTINST_ACCOUNT \ + --set spotinst.clusterIdentifier=$SPOTINST_CLUSTER_IDENTIFIER \ + --set spotinst.token=$SPOTINST_TOKEN \ + --set spotinst.proxyUrl=$SPOTINST_PROXY_URL \ + --set caBundleSecret.create=true \ + --set caBundleSecret.data="$(cat ./path/to/ca.pem)" +``` + +If you already have a CA bundle secret you can instead use: + +```sh +helm install spot spot/{{ template "chart.name" . }} \ + --set spotinst.account=$SPOTINST_ACCOUNT \ + --set spotinst.clusterIdentifier=$SPOTINST_CLUSTER_IDENTIFIER \ + --set spotinst.token=$SPOTINST_TOKEN \ + --set spotinst.proxyUrl=$SPOTINST_PROXY_URL \ + --set caBundleSecret.name=my-ca-bundle-secret \ + --set caBundleSecret.key=bundle.pem +``` + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/charts/ocean-right-sizing-controller/charts/metrics-server-3.12.2.tgz b/charts/ocean-right-sizing-controller/charts/metrics-server-3.12.2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4538e8a10e54c3dcb0d5047b4034cfb23683482e GIT binary patch literal 10395 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 F0RZYxsxJTl literal 0 HcmV?d00001 diff --git a/charts/ocean-right-sizing-controller/charts/ocean-vpa-1.0.4.tgz b/charts/ocean-right-sizing-controller/charts/ocean-vpa-1.0.4.tgz new file mode 100644 index 0000000000000000000000000000000000000000..1f13903cacf249533c2cf978d79c149c1358d09f GIT binary patch literal 11060 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 literal 0 HcmV?d00001 diff --git a/charts/ocean-right-sizing-controller/templates/_helpers.tpl b/charts/ocean-right-sizing-controller/templates/_helpers.tpl new file mode 100644 index 00000000..4b0a864f --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/_helpers.tpl @@ -0,0 +1,351 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "ocean-right-sizing-controller.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 "ocean-right-sizing-controller.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 for the auto-updater job. +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 "auto-updater.fullname" -}} +{{- if .Values.autoUpdate.fullnameOverride }} +{{- .Values.autoUpdate.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default "auto-updater" .Values.autoUpdate.nameOverride }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ocean-right-sizing-controller.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +The image to use +*/}} +{{- define "ocean-right-sizing-controller.image" -}} +{{- $imageSuffix := "" }} +{{- if and .Values.image.fips .Values.image.tag }} +{{- fail "`image.fips` should not be used together with `image.tag`. Either set `--image.fips=false` or `--image.tag=\"\"`" }} +{{- end }} +{{- if .Values.image.fips }} +{{- $imageSuffix = "-fips" }} +{{- end }} +{{- printf "%s:%s%s" .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) $imageSuffix }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "ocean-right-sizing-controller.labels" -}} +helm.sh/chart: {{ include "ocean-right-sizing-controller.chart" . }} +{{ include "ocean-right-sizing-controller.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "ocean-right-sizing-controller.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ocean-right-sizing-controller.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels Auto Updater +*/}} +{{- define "auto-updater.labels" -}} +helm.sh/chart: {{ include "ocean-right-sizing-controller.chart" . }} +{{ include "auto-updater.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels Auto Updater +*/}} +{{- define "auto-updater.selectorLabels" -}} +app.kubernetes.io/name: auto-updater +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +ConfigMap name. +*/}} +{{- define "ocean-right-sizing-controller.configMapName" -}} +{{ default (include "ocean-right-sizing-controller.fullname" .) .Values.configMap.name }} +{{- end }} + +{{/* +Secret name. +*/}} +{{- define "ocean-right-sizing-controller.secretName" -}} +{{ default (include "ocean-right-sizing-controller.fullname" .) .Values.secret.name }} +{{- end }} + +{{/* +CA bundle secret name. +*/}} +{{- define "ocean-right-sizing-controller.caBundleSecretName" -}} +{{ default (printf "%s-ca-bundle" (include "ocean-right-sizing-controller.fullname" .)) .Values.caBundleSecret.name }} +{{- end }} + +{{/* +ClusterRole name. +*/}} +{{- define "ocean-right-sizing-controller.clusterRoleName" -}} +{{ include "ocean-right-sizing-controller.fullname" . }} +{{- end }} + +{{/* +ClusterRoleBinding name. +*/}} +{{- define "ocean-right-sizing-controller.clusterRoleBindingName" -}} +{{ include "ocean-right-sizing-controller.fullname" . }} +{{- end }} + +{{/* +Create the name of the service-account to use +*/}} +{{- define "ocean-right-sizing-controller.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "ocean-right-sizing-controller.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service-account to use for the auto-updater +*/}} +{{- define "auto-updater.serviceAccountName" -}} +{{- if .Values.autoUpdate.serviceAccount.create }} +{{- default (include "auto-updater.fullname" .) .Values.autoUpdate.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.autoUpdate.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Controller default affinity +*/}} +{{- define "ocean-right-sizing-controller.defaultAffinity" -}} +nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: NotIn + values: + - windows + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + preference: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: Exists +{{- end }} + +{{/* +Controller default tolerations +*/}} +{{- define "ocean-right-sizing-controller.defaultTolerations" -}} +- key: node.kubernetes.io/not-ready + effect: NoExecute + operator: Exists + tolerationSeconds: 150 +- key: node.kubernetes.io/unreachable + effect: NoExecute + operator: Exists + tolerationSeconds: 150 +- key: node-role.kubernetes.io/master + operator: Exists +- key: node-role.kubernetes.io/control-plane + operator: Exists +- key: CriticalAddonsOnly + operator: Exists +{{- end }} + +{{/* +Controller affinity +*/}} +{{- define "ocean-right-sizing-controller.affinity" -}} +{{- if kindIs "invalid" .Values.affinity -}} +{{- include "ocean-right-sizing-controller.defaultAffinity" . -}} +{{- else }} +{{- .Values.affinity | toYaml -}} +{{- end }} +{{- end }} + +{{/* +Controller topology spread constraints +*/}} +{{- define "ocean-right-sizing-controller.topologySpreadConstraints" -}} +{{- if kindIs "invalid" .Values.topologySpreadConstraints -}} +- maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + {{- include "ocean-right-sizing-controller.selectorLabels" . | nindent 6 }} +{{- else }} +{{- .Values.topologySpreadConstraints | toYaml -}} +{{- end }} +{{- end }} + +{{/* +Auto-Updater affinity +*/}} +{{- define "auto-updater.affinity" -}} +{{- if kindIs "invalid" .Values.autoUpdate.affinity -}} +{{- include "ocean-right-sizing-controller.defaultAffinity" . -}} +{{- else }} +{{- .Values.autoUpdate.affinity | toYaml -}} +{{- end }} +{{- end }} + +{{/* +Auto-Updater tolerations +*/}} +{{- define "auto-updater.tolerations" -}} +{{- if kindIs "invalid" .Values.autoUpdate.tolerations -}} +- key: node.kubernetes.io/not-ready + effect: NoExecute + operator: Exists + tolerationSeconds: 150 +- key: node.kubernetes.io/unreachable + effect: NoExecute + operator: Exists + tolerationSeconds: 150 +- key: node-role.kubernetes.io/master + operator: Exists +- key: node-role.kubernetes.io/control-plane + operator: Exists +- key: CriticalAddonsOnly + operator: Exists +{{- else }} +{{- .Values.autoUpdate.tolerations | toYaml -}} +{{- end }} +{{- end }} + +{{/* +NO_PROXY environment variable +*/}} +{{- define "ocean-right-sizing-controller.noProxyEnvVar" -}} +{{- $hasNoProxyEnvVar := false -}} +{{- range .Values.extraEnv }} +{{- if eq .name "NO_PROXY" }} +{{- $hasNoProxyEnvVar = true }} +{{- end }} +{{- end }} +{{- if and .Values.spotinst.proxyUrl (not $hasNoProxyEnvVar) -}} +- name: NO_PROXY + value: '$(KUBERNETES_SERVICE_HOST)' # will be replaced to $(KUBERNETES_SERVICE_HOST) in cluster +{{ end -}} +{{- end }} + +{{/* +Metrics-server serviceaccount name +*/}} +{{- define "metrics-server.serviceAccountName" -}} +{{- $name := "metrics-server" }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Metrics-server fullname +*/}} +{{- define "metrics-server.fullname" -}} +{{- $name := "metrics-server" }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} + + +{{/* +Metrics-server name +*/}} +{{- define "metrics-server.name" -}} +metrics-server +{{- end }} + +{{/* +Figure out if we should deploy metrics server. We are checking: +- if 'metrics-server.deployChart' is true: + - try to fetch the 'v1beta1.metrics.k8s.io' APIService + - if it exists: + - check for it's helm annotations to see if it was installed as part of the + same release we are installing now (release name and namespace annotations). + - if it's not the same release -> fail +*/}} +{{- define "ocean-right-sizing-controller.deployMetricsServer" }} +{{- if (index .Values "metrics-server" "deployChart") }} +{{- $apiService := lookup "apiregistration.k8s.io/v1" "APIService" "" "v1beta1.metrics.k8s.io" }} +{{- $releaseName := .Release.Name }} +{{- $releaseNamespace := .Release.Namespace }} +{{- if $apiService -}} +{{- with $apiService }} +{{- if (or + (not .metadata.annotations) + (or + (ne + $releaseName + (index .metadata.annotations "meta.helm.sh/release-name") + ) + (ne + $releaseNamespace + (index .metadata.annotations "meta.helm.sh/release-namespace") + ) + )) +}} +{{- fail "\nThe value: 'metrics-server.deployChart' was set to 'true' but we found another installation of metrics-server in your cluster.\nYou must use:\n --set metrics-server.deployChart=false" }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Log Shipping - Should Enable + +Should only enabled log shipping if controller is installed against prod SaaS environment +or if another log shipping destination host is specified. +*/}} +{{- define "ocean-right-sizing-controller.logShipping.enabled" -}} +{{- if and .Values.logShipping .Values.logShipping.enabled -}} +{{- if (or + (or (eq .Values.spotinst.baseUrl "") (eq .Values.spotinst.baseUrl "api.spotinst.io:443")) + (ne .Values.logShipping.destination.host "api.spotinst.io") +) -}} +true +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/ocean-right-sizing-controller/templates/auto-update/_job.yaml b/charts/ocean-right-sizing-controller/templates/auto-update/_job.yaml new file mode 100644 index 00000000..771f5afb --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/auto-update/_job.yaml @@ -0,0 +1,85 @@ +{{- define "auto-updater.job" -}} +{{- if not .Values.spotinst.disableAutoUpdate -}} +apiVersion: batch/v1 +kind: Job +metadata: + generateName: {{ include "auto-updater.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "auto-updater.labels" . | nindent 4 }} +spec: + backoffLimit: 0 + ttlSecondsAfterFinished: 600 + template: + metadata: + labels: + {{- include "auto-updater.selectorLabels" . | nindent 8 }} + spec: + serviceAccountName: {{ include "auto-updater.serviceAccountName" . }} + restartPolicy: Never + {{- with .Values.autoUpdate.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.autoUpdate.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.autoUpdate.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + containers: + - name: auto-updater + image: {{ .Values.autoUpdate.image.repository }}:{{ .Values.autoUpdate.image.tag }} + imagePullPolicy: {{ .Values.autoUpdate.image.pullPolicy }} + command: + - /bin/bash + args: + - -c + - | + set -o pipefail + trap 'echo "SIGTERM caught"' INT TERM + + if [ -z "$CHART_VERSION" ]; then + echo "CHART_VERSION is not set" + exit 1 + fi + if [ -z "$WAIT_TIMEOUT" ]; then + echo "WAIT_TIMEOUT is not set" + exit 1 + fi + + export HELM_CACHE_HOME=/tmp/.helm + export HELM_CONFIG_HOME=/tmp/.helm + export HELM_DATA_HOME=/tmp/.helm + + echo "Upgrading release $(RELEASE_NAME) to version $(CHART_VERSION)" && \ + helm repo add spot https://charts.spot.io && \ + helm get values $(RELEASE_NAME) > /tmp/values.yaml && \ + helm upgrade $(RELEASE_NAME) spot/ocean-right-sizing-controller --version $(CHART_VERSION) \ + --atomic --timeout=$(WAIT_TIMEOUT) --values /tmp/values.yaml + securityContext: + {{- toYaml .Values.autoUpdate.securityContext | nindent 10 }} + env: + - name: RELEASE_NAME + value: {{ .Release.Name }} + resources: + {{- with .Values.autoUpdate.resources }} + {{- toYaml . | nindent 10 }} + {{- end }} + volumeMounts: + - name: helm-data + mountPath: /tmp + affinity: + {{- include "auto-updater.affinity" . | nindent 8 }} + tolerations: + {{- include "auto-updater.tolerations" . | nindent 6 }} + volumes: + - name: helm-data + emptyDir: {} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/auto-update/clusterrole.yaml b/charts/ocean-right-sizing-controller/templates/auto-update/clusterrole.yaml new file mode 100644 index 00000000..292133a0 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/auto-update/clusterrole.yaml @@ -0,0 +1,53 @@ +{{- if not .Values.spotinst.disableAutoUpdate }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "auto-updater.fullname" . }} + labels: + {{- include "auto-updater.labels" . | nindent 4 }} +rules: +# Auto Updater requires +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterrolebindings" ] + resourceNames: [ {{ include "auto-updater.fullname" . }} ] + verbs: [ "get", "patch" ] +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterroles" ] + resourceNames: [ {{ include "auto-updater.fullname" . }} ] + verbs: [ "get", "patch", "escalate", "bind" ] + +# Controller requires +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterroles" ] + verbs: [ "get", "patch", "escalate", "bind" ] + resourceNames: [ {{ include "ocean-right-sizing-controller.fullname" . }} ] +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterrolebindings" ] + verbs: [ "get", "patch" ] + resourceNames: [ {{ include "ocean-right-sizing-controller.fullname" . }} ] + +# Metrics Server requires +{{- if (index .Values "metrics-server" "deployChart") }} +- apiGroups: [ "apiregistration.k8s.io" ] + resources: [ "apiservices" ] + resourceNames: [ "v1beta1.metrics.k8s.io" ] + verbs: [ "get", "patch" ] +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterroles" ] + verbs: [ "get", "patch", "escalate", "bind" ] + resourceNames: + - {{ printf "system:%s" (include "metrics-server.fullname" .) }} + - {{ printf "system:%s-aggregated-reader" (include "metrics-server.name" .) }} +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterrolebindings" ] + verbs: [ "get", "patch" ] + resourceNames: + - {{ printf "system:%s" (include "metrics-server.fullname" .) }} + - {{ printf "%s:system:auth-delegator" (include "metrics-server.fullname" .) }} +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "rolebindings" ] + verbs: [ "get", "patch" ] + resourceNames: + - {{ printf "%s-auth-reader" (include "metrics-server.fullname" .) }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/auto-update/clusterrolebinding.yaml b/charts/ocean-right-sizing-controller/templates/auto-update/clusterrolebinding.yaml new file mode 100644 index 00000000..6811aea0 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/auto-update/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if not .Values.spotinst.disableAutoUpdate }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "auto-updater.fullname" . }} + labels: + {{- include "auto-updater.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "auto-updater.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "auto-updater.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/auto-update/role.yaml b/charts/ocean-right-sizing-controller/templates/auto-update/role.yaml new file mode 100644 index 00000000..503056f5 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/auto-update/role.yaml @@ -0,0 +1,82 @@ +{{- if not .Values.spotinst.disableAutoUpdate }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "auto-updater.fullname" . }} + labels: + {{- include "auto-updater.labels" . | nindent 4 }} +rules: +# Auto Updater requires +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "rolebindings" ] + resourceNames: [ {{ include "auto-updater.fullname" . }} ] + verbs: [ "get", "patch" ] +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "roles" ] + resourceNames: [ {{ include "auto-updater.fullname" . }} ] + verbs: [ "get", "patch", "escalate", "bind" ] +- apiGroups: [ "" ] + resources: [ "serviceaccounts" ] + resourceNames: [ {{ include "auto-updater.fullname" . }} ] + verbs: [ "get", "patch" ] +# Helm Management (resource name not required because the name is dynamic) +- apiGroups: [ "" ] + resources: [ "secrets" ] + verbs: [ "create", "get", "update", "list", "delete" ] +# Required to monitor the deployments rollout after the upgrade +# (resource name not required because the name is dynamic) +- apiGroups: [ "apps" ] + resources: [ "replicasets" ] + verbs: [ "list", "watch" ] + +# Controller requires +- apiGroups: [ "apps" ] + resources: [ "deployments" ] + resourceNames: [ {{ include "ocean-right-sizing-controller.fullname" . }} ] + verbs: [ "get", "patch" ] +- apiGroups: [ "" ] + resources: [ "configmaps" ] + resourceNames: [ {{ include "ocean-right-sizing-controller.configMapName" . }} ] + verbs: [ "get", "patch" ] +- apiGroups: [ "" ] + resources: [ "secrets" ] + resourceNames: [ {{ include "ocean-right-sizing-controller.secretName" . }} ] + verbs: [ "get", "patch" ] +- apiGroups: [ "" ] + resources: [ "serviceaccounts" ] + resourceNames: [ {{ include "ocean-right-sizing-controller.serviceAccountName" . }} ] + verbs: [ "get", "patch" ] +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "roles" ] + resourceNames: [ {{ include "ocean-right-sizing-controller.fullname" . }} ] + verbs: [ "get", "patch", "escalate", "bind" ] +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "rolebindings" ] + resourceNames: [ {{ include "ocean-right-sizing-controller.fullname" . }} ] + verbs: [ "get", "patch" ] +{{- if and (ne .Release.Namespace "kube-system") .Values.resourceQuota.enabled }} +- apiGroups: [ "" ] + # Cannot limit to specific resource name due to limitation with K8s RBAC. + # We need to create this resource with the auto-updater and it will not allow + # 'create' verb if we limit to specific resource name. + # resourceNames: [ {{ include "ocean-right-sizing-controller.fullname" . }} ] + resources: [ "resourcequotas" ] + verbs: [ "get", "patch", "create" ] +{{- end }} + +# Metrics Server requires +{{- if (index .Values "metrics-server" "deployChart") }} +- apiGroups: [ "" ] + resources: [ "serviceaccounts" ] + resourceNames: [ {{ include "metrics-server.serviceAccountName" . }} ] + verbs: [ "get", "patch" ] +- apiGroups: [ "" ] + resources: [ "services" ] + resourceNames: [ {{ include "metrics-server.fullname" . }} ] + verbs: [ "get", "patch" ] +- apiGroups: [ "apps" ] + resources: [ "deployments" ] + resourceNames: [ {{ include "metrics-server.fullname" . }} ] + verbs: [ "get", "patch" ] +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/auto-update/rolebinding.yaml b/charts/ocean-right-sizing-controller/templates/auto-update/rolebinding.yaml new file mode 100644 index 00000000..f8ff5936 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/auto-update/rolebinding.yaml @@ -0,0 +1,15 @@ +{{- if not .Values.spotinst.disableAutoUpdate }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "auto-updater.fullname" . }} + labels: + {{- include "auto-updater.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "auto-updater.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "auto-updater.serviceAccountName" . }} +{{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/auto-update/serviceaccount.yaml b/charts/ocean-right-sizing-controller/templates/auto-update/serviceaccount.yaml new file mode 100644 index 00000000..8ca23a1c --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/auto-update/serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if not .Values.spotinst.disableAutoUpdate }} +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "auto-updater.serviceAccountName" . }} + labels: + {{- include "auto-updater.labels" . | nindent 4 }} + {{- with .Values.autoUpdate.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/caBundle.secret.yaml b/charts/ocean-right-sizing-controller/templates/caBundle.secret.yaml new file mode 100644 index 00000000..5a4a49bf --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/caBundle.secret.yaml @@ -0,0 +1,11 @@ +{{- if .Values.caBundleSecret.create }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "ocean-right-sizing-controller.caBundleSecretName" . }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +type: Opaque +data: + {{- .Values.caBundleSecret.key | nindent 2 -}}: {{ required "`caBundleSecret.data` must be specified if `caBundleSecret.create` is `true`" .Values.caBundleSecret.data | b64enc }} +{{- end }} diff --git a/charts/ocean-right-sizing-controller/templates/clusterrole.yaml b/charts/ocean-right-sizing-controller/templates/clusterrole.yaml new file mode 100644 index 00000000..cce7860f --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/clusterrole.yaml @@ -0,0 +1,65 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "ocean-right-sizing-controller.fullname" . }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +rules: + # --------------------------------------------------------------------------- + # feature: ocean/readonly + # --------------------------------------------------------------------------- +- apiGroups: [ "" ] + resources: [ "pods", "nodes", "services", "namespaces", "replicationcontrollers", "limitranges", "events", "persistentvolumes", "persistentvolumeclaims" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "apps" ] + resources: [ "deployments", "daemonsets", "statefulsets", "replicasets" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "storage.k8s.io" ] + resources: [ "storageclasses" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "batch" ] + resources: [ "jobs", "cronjobs" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "policy" ] + resources: [ "poddisruptionbudgets" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "metrics.k8s.io" ] + resources: [ "pods" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "autoscaling" ] + resources: [ "horizontalpodautoscalers" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "autoscaling.k8s.io" ] + resources: [ "verticalpodautoscalers" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "apiextensions.k8s.io" ] + resources: [ "customresourcedefinitions" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "node.k8s.io" ] + resources: [ "runtimeclasses" ] + verbs: [ "get", "list", "watch" ] +- nonResourceURLs: [ "/version/", "/version" ] + verbs: [ "get" ] + + # --------------------------------------------------------------------------- + # feature: controller/leader-election (high-availability) + # --------------------------------------------------------------------------- +- apiGroups: [ "coordination.k8s.io" ] + resources: [ "leases" ] + verbs: [ "get","list","patch","update","create","delete" ] + + # --------------------------------------------------------------------------- + # feature: automatic right-sizing + # --------------------------------------------------------------------------- +- apiGroups: ["autoscaling.k8s.io"] + resources: ["verticalpodautoscalers", "verticalpodautoscalers/status"] + verbs: ["get", "list", "watch", "patch", "update", "create", "delete"] +- apiGroups: ["autoscaling"] + resources: ["horizontalpodautoscalers"] + verbs: ["patch", "update"] +- apiGroups: [ "" ] + resources: [ "pods"] + verbs: [ "get", "list", "patch", "update", "create", "delete" ] +- apiGroups: ["apps"] + resources: ["deployments", "daemonsets", "statefulsets", "replicasets"] + verbs: [ "get", "list", "watch", "patch", "update" ] \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/clusterrolebinding.yaml b/charts/ocean-right-sizing-controller/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..1c6f180c --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/clusterrolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "ocean-right-sizing-controller.fullname" . }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "ocean-right-sizing-controller.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "ocean-right-sizing-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/charts/ocean-right-sizing-controller/templates/configmap.yaml b/charts/ocean-right-sizing-controller/templates/configmap.yaml new file mode 100644 index 00000000..398b223a --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/configmap.yaml @@ -0,0 +1,109 @@ +{{- if .Values.configMap.create }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +data: + spotinst.cluster-identifier: {{ required "`spotinst.clusterIdentifier` must be specified" .Values.spotinst.clusterIdentifier }} + base-url: {{ default "" .Values.spotinst.baseUrl | quote }} + proxy-url: {{ default "" .Values.spotinst.proxyUrl | quote }} + leader-election: {{ gt (int .Values.replicas) 1 | quote }} + disable-auto-update: {{ default "false" .Values.spotinst.disableAutoUpdate | quote }} + enable-csr-approval: {{ default "false" .Values.spotinst.enableCsrApproval | quote }} + {{- if not .Values.spotinst.disableAutoUpdate }} + auto-update.job: | + {{- include "auto-updater.job" . | nindent 4 }} + {{- end }} + {{- if eq (include "ocean-right-sizing-controller.logShipping.enabled" .) "true" }} + fluent-bit.conf: | + [SERVICE] + Parsers_File parsers.conf + Flush 60 + Daemon Off + + [INPUT] + Name tail + Path /var/log/controller.logs + Parser json + Buffer_Max_Size 2MB + Skip_Long_Lines On + Skip_Empty_Lines On + Refresh_Interval 10 + + [FILTER] + Name modify + Match * + Add ctrlPod ${POD_NAMESPACE}/${POD_NAME} + + # rename msg -> message , level -> l + [FILTER] + Name modify + Match * + Rename msg message + Rename level l + + # info -> INFO + [FILTER] + Name modify + Match * + + Condition Key_Value_Equals l info + SET l INFO + + # debug -> INFO + [FILTER] + Name modify + Match * + + Condition Key_Value_Equals l debug + SET l INFO + + # trace -> TRACE + [FILTER] + Name modify + Match * + + Condition Key_Value_Equals l trace + SET l TRACE + + # error -> ERROR + [FILTER] + Name modify + Match * + + Condition Key_Value_Equals l error + SET l ERROR + + # nest all fields under log key + [FILTER] + Name nest + Match * + Operation nest + Wildcard * + Nest_Under log + + # stringify log field + [FILTER] + Name Lua + Match * + call parse + code function stringify(obj) result = {} for key, value in pairs(obj) do table.insert(result, string.format("\"%s\":%q", key, value)) end result = "{" .. table.concat(result, ",") .. "}" return result end function parse(tag, timestamp, record) new_record = record new_record["log"] = stringify(record["log"]) return 1, timestamp, new_record end + + [OUTPUT] + Name http + Match * + Format json + Host {{ .Values.logShipping.destination.host }} + Port {{ .Values.logShipping.destination.port }} + TLS {{ .Values.logShipping.destination.tls }} + URI /logs/${CLUSTER_IDENTIFIER}?accountId=${SPOTINST_ACCOUNT} + Header Authorization Bearer ${SPOTINST_TOKEN} + Retry_Limit no_retries + parsers.conf: | + [PARSER] + Name json + Format json + {{- end }} +{{- end }} diff --git a/charts/ocean-right-sizing-controller/templates/deployment.yaml b/charts/ocean-right-sizing-controller/templates/deployment.yaml new file mode 100644 index 00000000..bd43e1d7 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/deployment.yaml @@ -0,0 +1,263 @@ +{{ include "ocean-right-sizing-controller.deployMetricsServer" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ocean-right-sizing-controller.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicas }} + {{- with .Values.updateStrategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "ocean-right-sizing-controller.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + # This will restart the deployment in case of configmap/secret/cluster-role changes + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + checksum/cluster-role: {{ include (print $.Template.BasePath "/clusterrole.yaml") . | sha256sum }} + kubectl.kubernetes.io/default-container: {{ .Chart.Name }} + + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "ocean-right-sizing-controller.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "ocean-right-sizing-controller.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- with .Values.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ include "ocean-right-sizing-controller.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.command }} + command: + {{- toYaml . | nindent 12 }} + {{- end }} + args: + {{- range .Values.args }} + - {{ . }} + {{- end }} + {{- if eq (include "ocean-right-sizing-controller.logShipping.enabled" .) "true" }} + - --log_to_file + - --log_file=/var/log/controller.logs + - --log_file_max_size=1 + {{- end }} + {{- if .Values.spotinst.insecureSkipTLSVerify }} + - --insecure + {{- end }} + env: + - name: SPOTINST_TOKEN + valueFrom: + secretKeyRef: + name: {{ include "ocean-right-sizing-controller.secretName" . }} + key: token + - name: SPOTINST_ACCOUNT + valueFrom: + secretKeyRef: + name: {{ include "ocean-right-sizing-controller.secretName" . }} + key: account + - name: SPOTINST_LEADER_ELECTION_ENABLED + valueFrom: + configMapKeyRef: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + key: leader-election + optional: true + - name: CLUSTER_IDENTIFIER + valueFrom: + configMapKeyRef: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + key: spotinst.cluster-identifier + - name: BASE_SPOTINST_URL + valueFrom: + configMapKeyRef: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + key: base-url + optional: true + - name: HTTPS_PROXY + valueFrom: + configMapKeyRef: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + key: proxy-url + optional: true + - name: DISABLE_AUTO_UPDATE + valueFrom: + configMapKeyRef: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + key: disable-auto-update + optional: true + {{- if .Values.spotinst.readonly}} + - name: SPOTINST_READONLY_MODE + value: "true" + {{- end }} + {{- if not .Values.spotinst.disableAutoUpdate }} + - name: AUTO_UPDATE_JOB_SPEC + valueFrom: + configMapKeyRef: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + key: auto-update.job + optional: true + {{- end }} + - name: ENABLE_CSR_APPROVAL + valueFrom: + configMapKeyRef: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + key: enable-csr-approval + optional: true + - name: USER_ENV_CERTIFICATES + valueFrom: + secretKeyRef: + name: {{ include "ocean-right-sizing-controller.caBundleSecretName" . }} + key: {{ .Values.caBundleSecret.key }} + optional: true + - name: POD_ID + valueFrom: + fieldRef: + fieldPath: metadata.uid + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- include "ocean-right-sizing-controller.noProxyEnvVar" . | nindent 10 -}} + ports: + - name: metrics + containerPort: 9080 + - name: readiness + containerPort: 9081 + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if eq (include "ocean-right-sizing-controller.logShipping.enabled" .) "true" }} + - name: logs + mountPath: /var/log + {{- end }} + resources: + {{- with .Values.resources }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if eq (include "ocean-right-sizing-controller.logShipping.enabled" .) "true" }} + - name: log-shipper + image: {{ .Values.logShipping.image.repository }}:{{ .Values.logShipping.image.tag }} + imagePullPolicy: {{ .Values.logShipping.image.pullPolicy }} + {{- with .Values.logShipping.command }} + command: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: SPOTINST_TOKEN + valueFrom: + secretKeyRef: + name: {{ include "ocean-right-sizing-controller.secretName" . }} + key: token + optional: true + - name: SPOTINST_ACCOUNT + valueFrom: + secretKeyRef: + name: {{ include "ocean-right-sizing-controller.secretName" . }} + key: account + optional: true + - name: CLUSTER_IDENTIFIER + valueFrom: + configMapKeyRef: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + key: spotinst.cluster-identifier + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- with .Values.logShipping.extraEnv }} + {{- toYaml . | nindent 10 }} + {{- end }} + volumeMounts: + - name: logs + mountPath: /var/log + - name: fluentbit-config + mountPath: /tmp/fluent-bit.conf + subPath: fluent-bit.conf + - name: fluentbit-config + mountPath: /tmp/parsers.conf + subPath: parsers.conf + {{- with .Values.logShipping.extraVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + securityContext: + {{- toYaml .Values.logShipping.securityContext | nindent 12 }} + {{- end }} + volumes: + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- if eq (include "ocean-right-sizing-controller.logShipping.enabled" .) "true" }} + - name: logs + emptyDir: {} + - name: fluentbit-config + configMap: + name: {{ include "ocean-right-sizing-controller.configMapName" . }} + items: + - key: fluent-bit.conf + path: fluent-bit.conf + - key: parsers.conf + path: parsers.conf + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + affinity: + {{- include "ocean-right-sizing-controller.affinity" . | nindent 8 }} + {{- if kindIs "invalid" .Values.tolerations }} + tolerations: + {{- include "ocean-right-sizing-controller.defaultTolerations" . | nindent 6 }} + {{- else }} + {{- with .Values.tolerations }} + tolerations: + {{- . | toYaml | nindent 6 }} + {{- end }} + {{- end }} + topologySpreadConstraints: + {{- include "ocean-right-sizing-controller.topologySpreadConstraints" . | nindent 6 }} diff --git a/charts/ocean-right-sizing-controller/templates/resourcequota.yaml b/charts/ocean-right-sizing-controller/templates/resourcequota.yaml new file mode 100644 index 00000000..ae5026f1 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/resourcequota.yaml @@ -0,0 +1,19 @@ +{{- if and (ne .Release.Namespace "kube-system") .Values.resourceQuota.enabled }} +apiVersion: v1 +kind: ResourceQuota +metadata: + name: {{ include "ocean-right-sizing-controller.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +spec: + hard: + pods: "1000" + scopeSelector: + matchExpressions: + - operator: In + scopeName: PriorityClass + values: + - system-node-critical + - system-cluster-critical +{{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/role.yaml b/charts/ocean-right-sizing-controller/templates/role.yaml new file mode 100644 index 00000000..20b0bdea --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/role.yaml @@ -0,0 +1,14 @@ +{{- if not .Values.spotinst.disableAutoUpdate }} +# This role is required only to fetch the logs of the auto-updater job. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "ocean-right-sizing-controller.fullname" . }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +rules: + # Get logs of the auto-updater job + - apiGroups: [ "" ] + resources: [ "pods/log" ] + verbs: [ "get" ] +{{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/rolebinding.yaml b/charts/ocean-right-sizing-controller/templates/rolebinding.yaml new file mode 100644 index 00000000..35261a11 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/rolebinding.yaml @@ -0,0 +1,15 @@ +{{- if not .Values.spotinst.disableAutoUpdate }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "ocean-right-sizing-controller.fullname" . }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "ocean-right-sizing-controller.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "ocean-right-sizing-controller.serviceAccountName" . }} +{{- end }} diff --git a/charts/ocean-right-sizing-controller/templates/secret.yaml b/charts/ocean-right-sizing-controller/templates/secret.yaml new file mode 100644 index 00000000..d01b1b37 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/secret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.secret.create }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "ocean-right-sizing-controller.secretName" . }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} +type: Opaque +data: + token: {{ required "`spotinst.token` must be specified" .Values.spotinst.token | b64enc }} + account: {{ required "`spotinst.account` must be specified" .Values.spotinst.account | b64enc }} +{{- end }} diff --git a/charts/ocean-right-sizing-controller/templates/serviceaccount.yaml b/charts/ocean-right-sizing-controller/templates/serviceaccount.yaml new file mode 100644 index 00000000..42d4b007 --- /dev/null +++ b/charts/ocean-right-sizing-controller/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "ocean-right-sizing-controller.serviceAccountName" . }} + labels: + {{- include "ocean-right-sizing-controller.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/ocean-right-sizing-controller/values.yaml b/charts/ocean-right-sizing-controller/values.yaml new file mode 100644 index 00000000..84081f0e --- /dev/null +++ b/charts/ocean-right-sizing-controller/values.yaml @@ -0,0 +1,301 @@ +# Default values for ocean-right-sizing-controller. + +nameOverride: "" +fullnameOverride: "" + +# Spot Configuration. +spotinst: + # -- Spot Token. (Required) + # Ref: https://docs.spot.io/administration/api/create-api-token + token: "" + # -- Spot Account ID. (Required) + # Example: `act-123abcd` + account: "" + # -- Unique identifier used by the Ocean Controller to connect (Required) + # between the Ocean backend and the Kubernetes cluster. + # Ref: https://docs.spot.io/ocean/tutorials/spot-kubernetes-controller/ + clusterIdentifier: "" + # -- Base URL. (Optional) + baseUrl: "" + # -- Proxy URL. (Optional) + proxyUrl: "" + # -- Disable auto update. (Optional) + disableAutoUpdate: false + # -- Enable CSR approval. (Optional) + enableCsrApproval: true + # -- Disable TLS certificate validation. (Optional) + insecureSkipTLSVerify: false + # -- Whether this controller needs to be readonly - overrides other permissions. (Optional) + readonly: true +# -- Configure the amount of replicas for the controller (Optional) +replicas: 2 + +image: + repository: us-docker.pkg.dev/spotit-today/container-labs/spotinst-kubernetes-controller + pullPolicy: IfNotPresent + # -- Overrides the image tag whose default is the chart appVersion. + tag: "" + # -- Set to `true` to use an FIPS-140 compliant image. This flag adds `-fips` suffix to the image tag, + # therefore it should not be used together with the `--image.tag` flag. + # Ref: https://go.dev/doc/security/fips140 + fips: false + +initContainers: [] + +imagePullSecrets: [] + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. (Optional) + name: "" + +secret: + # -- Controls whether a Secret should be created. (Optional) + create: true + # -- Secret name. (Optional) + name: "" + +# CA bundle. +# Ref: https://kubernetes.io/docs/concepts/configuration/secret/ +caBundleSecret: + # -- CA bundle Secret name. (Optional) + name: "" + # -- Key inside the secret to inject the CA bundle from + key: "userEnvCertificates.pem" + # -- Controls whether a CA bundle secret should be created. + create: false + # -- Must contain the CA bundle data in case `caBundleSecret.create` is true. + # For example by using `--set caBundleSecret.data="$(cat ./ca.pem)"` + data: "" + +# Config Map. +# Ref: https://kubernetes.io/docs/concepts/configuration/configmap/ +configMap: + create: true + # -- ConfigMap name. (Optional) + name: "" + +podAnnotations: {} +podLabels: {} +commonLabels: {} + +# Pod Security Context +# Ref: https://kubernetes.io/docs/concepts/security/pod-security-standards/ +podSecurityContext: + runAsNonRoot: true + runAsUser: 1000690000 + runAsGroup: 1000690000 + fsGroup: 1000690000 + +# -- Priority class name for the controller pod. +priorityClassName: system-node-critical + +# -- Resource Quota configuration. Required when running in a namespace other than kube-system in GKE. +# Ref: https://kubernetes.io/docs/concepts/policy/resource-quotas/ +resourceQuota: + enabled: true + +# Container Security Context +securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + +command: [] + +args: [] +# - --test + +extraEnv: [] +# - name: KEY +# value: VALUE + +livenessProbe: + httpGet: + path: /healthz + port: readiness + initialDelaySeconds: 15 + periodSeconds: 20 + +readinessProbe: + httpGet: + path: /readyz + port: readiness + initialDelaySeconds: 5 + periodSeconds: 10 + +# Controller pod resources. (Optional) +resources: {} + # requests: + # cpu: 100m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +# -- Tolerations for nodes that have taints on them. (Optional) +# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: +# - key: node.kubernetes.io/not-ready +# effect: NoExecute +# operator: Exists +# tolerationSeconds: 150 + +# Pod scheduling preferences. +# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: +# podAntiAffinity: +# preferredDuringSchedulingIgnoredDuringExecution: +# - weight: 50 +# podAffinityTerm: +# labelSelector: +# matchExpressions: +# - key: app.kubernetes.io/name +# operator: In +# values: +# - spotinst-kubernetes-cluster-controller +# topologyKey: kubernetes.io/hostname + +topologySpreadConstraints: +# - maxSkew: 1 +# topologyKey: kubernetes.io/hostname +# whenUnsatisfiable: ScheduleAnyway +# labelSelector: +# app: test + +extraVolumeMounts: [] + +extraVolumes: [] + +schedulerName: "" + +# Annotations to add to the deployment +deploymentAnnotations: {} + +# Deployment update strategy +updateStrategy: {} +# type: RollingUpdate +# rollingUpdate: +# maxSurge: 0 +# maxUnavailable: 1 + +# Metrics Server configuration. +metrics-server: + # -- Specifies whether the metrics-server chart should be deployed. + deployChart: true + + # Overrides the image + image: + repository: registry.k8s.io/metrics-server/metrics-server + tag: "" + pullPolicy: IfNotPresent + + # -- Arguments to pass to metrics-server on start up. (Optional) + # args: + # enable this if you have self-signed certificates, see: https://github.com/kubernetes-incubator/metrics-server + # - --kubelet-insecure-tls + +# Ocean VPA configuration. +ocean-vpa: + # -- Specifies whether the ocean-vpa chart should be deployed. + deployChart: true + +# -- Log Shipping configuration. +logShipping: + # -- Specifies whether to send the controller logs to Spot for analysis. (Optional) + enabled: true + + image: + # -- Image repository. (Optional) + repository: ghcr.io/fluent/fluent-bit + # -- Overrides the image tag. (Optional) + tag: "3.1.9" + # -- Image pull policy. (Optional) + pullPolicy: IfNotPresent + + # -- Log shipping destination configuration. + destination: + host: api.spotinst.io + port: 443 + tls: true + + extraVolumeMounts: [] + + extraEnv: [] + + # -- Log shipping container command. (Optional) + command: + - /fluent-bit/bin/fluent-bit + - -c + - /tmp/fluent-bit.conf + - -q + + # -- Log Shipping container security context + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + +# Auto Update process configuration. +autoUpdate: + # -- Configures the image for the auto-updater job. (Optional) + image: + # -- Image repository. (Optional) + repository: us-docker.pkg.dev/spotit-today/container-labs/auto-updater + # -- Overrides the image tag. (Optional) + tag: "latest" + # -- Image pull policy. (Optional) + pullPolicy: Always + + # -- Image pull secrets. (Optional) + imagePullSecrets: [] + + # -- Pod Security Context for the auto-updater job. (Optional) + # Ref: https://kubernetes.io/docs/concepts/security/pod-security-standards/ + podSecurityContext: + runAsNonRoot: true + runAsUser: 1000690000 + runAsGroup: 1000690000 + fsGroup: 1000690000 + + # -- Security Context for the auto-updater container. (Optional) + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + + # -- Resource requests and limits for the auto-updater job. + # Defaults to 100m CPU and 256Mi memory to make the job run with 'Guranteed' QoS. (Optional) + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 100m + memory: 256Mi + + # -- Priority class name for the auto-updater job. + # Defaults to the same priority class as the controller to prevent eviction. (Optional) + priorityClassName: system-cluster-critical + + serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. (Optional) + name: "" From 3a875ba441662e16b5e88b3aafb6268071294c42 Mon Sep 17 00:00:00 2001 From: atarasov Date: Thu, 19 Jun 2025 11:51:31 +0300 Subject: [PATCH 2/3] CON-34562 - helm-docs --- .../ocean-right-sizing-controller/README.md | 188 +++++++++--------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/charts/ocean-right-sizing-controller/README.md b/charts/ocean-right-sizing-controller/README.md index e8f6619a..f3eef272 100644 --- a/charts/ocean-right-sizing-controller/README.md +++ b/charts/ocean-right-sizing-controller/README.md @@ -59,103 +59,103 @@ helm install spot spot/ocean-right-sizing-controller \ Kubernetes: `>=1.20.0-0` -| Repository | Name | Version | -|--------------------------------------------------|----------------|---------| -| https://charts.spot.io | ocean-vpa | 1.0.4 | -| https://kubernetes-sigs.github.io/metrics-server | metrics-server | 3.12.2 | +| Repository | Name | Version | +|------------|------|---------| +| https://charts.spot.io | ocean-vpa | 1.0.4 | +| https://kubernetes-sigs.github.io/metrics-server | metrics-server | 3.12.2 | ## Values -| Key | Type | Default | Description | -|------------------------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| affinity | string | `nil` | | -| args | list | `[]` | | -| autoUpdate.image | object | `{"pullPolicy":"Always","repository":"us-docker.pkg.dev/spotit-today/container-labs/auto-updater","tag":"latest"}` | Configures the image for the auto-updater job. (Optional) | -| autoUpdate.image.pullPolicy | string | `"Always"` | Image pull policy. (Optional) | -| autoUpdate.image.repository | string | `"us-docker.pkg.dev/spotit-today/container-labs/auto-updater"` | Image repository. (Optional) | -| autoUpdate.image.tag | string | `"latest"` | Overrides the image tag. (Optional) | -| autoUpdate.imagePullSecrets | list | `[]` | Image pull secrets. (Optional) | -| autoUpdate.podSecurityContext | object | `{"fsGroup":1000690000,"runAsGroup":1000690000,"runAsNonRoot":true,"runAsUser":1000690000}` | Pod Security Context for the auto-updater job. (Optional) Ref: https://kubernetes.io/docs/concepts/security/pod-security-standards/ | -| autoUpdate.priorityClassName | string | `"system-cluster-critical"` | Priority class name for the auto-updater job. Defaults to the same priority class as the controller to prevent eviction. (Optional) | -| autoUpdate.resources | object | `{"limits":{"cpu":"100m","memory":"256Mi"},"requests":{"cpu":"100m","memory":"256Mi"}}` | Resource requests and limits for the auto-updater job. Defaults to 100m CPU and 256Mi memory to make the job run with 'Guranteed' QoS. (Optional) | -| autoUpdate.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}` | Security Context for the auto-updater container. (Optional) | -| autoUpdate.serviceAccount.annotations | object | `{}` | | -| autoUpdate.serviceAccount.create | bool | `true` | | -| autoUpdate.serviceAccount.name | string | `""` | | -| caBundleSecret.create | bool | `false` | Controls whether a CA bundle secret should be created. | -| caBundleSecret.data | string | `""` | Must contain the CA bundle data in case `caBundleSecret.create` is true. For example by using `--set caBundleSecret.data="$(cat ./ca.pem)"` | -| caBundleSecret.key | string | `"userEnvCertificates.pem"` | Key inside the secret to inject the CA bundle from | -| caBundleSecret.name | string | `""` | CA bundle Secret name. (Optional) | -| command | list | `[]` | | -| commonLabels | object | `{}` | | -| configMap.create | bool | `true` | | -| configMap.name | string | `""` | ConfigMap name. (Optional) | -| deploymentAnnotations | object | `{}` | | -| extraEnv | list | `[]` | | -| extraVolumeMounts | list | `[]` | | -| extraVolumes | list | `[]` | | -| fullnameOverride | string | `""` | | -| image.fips | bool | `false` | Set to `true` to use an FIPS-140 compliant image. This flag adds `-fips` suffix to the image tag, therefore it should not be used together with the `--image.tag` flag. Ref: https://go.dev/doc/security/fips140 | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.repository | string | `"us-docker.pkg.dev/spotit-today/container-labs/spotinst-kubernetes-controller"` | | -| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | -| imagePullSecrets | list | `[]` | | -| initContainers | list | `[]` | | -| livenessProbe.httpGet.path | string | `"/healthz"` | | -| livenessProbe.httpGet.port | string | `"readiness"` | | -| livenessProbe.initialDelaySeconds | int | `15` | | -| livenessProbe.periodSeconds | int | `20` | | -| logShipping | object | `{"command":["/fluent-bit/bin/fluent-bit","-c","/tmp/fluent-bit.conf","-q"],"destination":{"host":"api.spotinst.io","port":443,"tls":true},"enabled":true,"extraEnv":[],"extraVolumeMounts":[],"image":{"pullPolicy":"IfNotPresent","repository":"ghcr.io/fluent/fluent-bit","tag":"3.1.9"},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}}` | Log Shipping configuration. | -| logShipping.command | list | `["/fluent-bit/bin/fluent-bit","-c","/tmp/fluent-bit.conf","-q"]` | Log shipping container command. (Optional) | -| logShipping.destination | object | `{"host":"api.spotinst.io","port":443,"tls":true}` | Log shipping destination configuration. | -| logShipping.enabled | bool | `true` | Specifies whether to send the controller logs to Spot for analysis. (Optional) | -| logShipping.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. (Optional) | -| logShipping.image.repository | string | `"ghcr.io/fluent/fluent-bit"` | Image repository. (Optional) | -| logShipping.image.tag | string | `"3.1.9"` | Overrides the image tag. (Optional) | -| logShipping.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}` | Log Shipping container security context | -| metrics-server.deployChart | bool | `true` | Specifies whether the metrics-server chart should be deployed. | -| metrics-server.image.pullPolicy | string | `"IfNotPresent"` | | -| metrics-server.image.repository | string | `"registry.k8s.io/metrics-server/metrics-server"` | | -| metrics-server.image.tag | string | `""` | | -| nameOverride | string | `""` | | -| nodeSelector | object | `{}` | | -| ocean-vpa.deployChart | bool | `true` | Specifies whether the ocean-vpa chart should be deployed. | -| podAnnotations | object | `{}` | | -| podLabels | object | `{}` | | -| podSecurityContext.fsGroup | int | `1000690000` | | -| podSecurityContext.runAsGroup | int | `1000690000` | | -| podSecurityContext.runAsNonRoot | bool | `true` | | -| podSecurityContext.runAsUser | int | `1000690000` | | -| priorityClassName | string | `"system-node-critical"` | Priority class name for the controller pod. | -| readinessProbe.httpGet.path | string | `"/readyz"` | | -| readinessProbe.httpGet.port | string | `"readiness"` | | -| readinessProbe.initialDelaySeconds | int | `5` | | -| readinessProbe.periodSeconds | int | `10` | | -| replicas | int | `2` | Configure the amount of replicas for the controller (Optional) | -| resourceQuota | object | `{"enabled":true}` | Resource Quota configuration. Required when running in a namespace other than kube-system in GKE. Ref: https://kubernetes.io/docs/concepts/policy/resource-quotas/ | -| resources | object | `{}` | | -| schedulerName | string | `""` | | -| secret.create | bool | `true` | Controls whether a Secret should be created. (Optional) | -| secret.name | string | `""` | Secret name. (Optional) | -| securityContext.allowPrivilegeEscalation | bool | `false` | | -| securityContext.capabilities.drop[0] | string | `"ALL"` | | -| securityContext.readOnlyRootFilesystem | bool | `true` | | -| securityContext.runAsNonRoot | bool | `true` | | -| serviceAccount.annotations | object | `{}` | | -| serviceAccount.create | bool | `true` | | -| serviceAccount.name | string | `""` | | -| spotinst.account | string | `""` | Spot Account ID. (Required) Example: `act-123abcd` | -| spotinst.baseUrl | string | `""` | Base URL. (Optional) | -| spotinst.clusterIdentifier | string | `""` | Unique identifier used by the Ocean Controller to connect (Required) between the Ocean backend and the Kubernetes cluster. Ref: https://docs.spot.io/ocean/tutorials/spot-kubernetes-controller/ | -| spotinst.disableAutoUpdate | bool | `false` | Disable auto update. (Optional) | -| spotinst.enableCsrApproval | bool | `true` | Enable CSR approval. (Optional) | -| spotinst.insecureSkipTLSVerify | bool | `false` | Disable TLS certificate validation. (Optional) | -| spotinst.proxyUrl | string | `""` | Proxy URL. (Optional) | -| spotinst.readonly | bool | `true` | Whether this controller needs to be readonly - overrides other permissions. (Optional) | -| spotinst.token | string | `""` | Spot Token. (Required) Ref: https://docs.spot.io/administration/api/create-api-token | -| tolerations | string | `nil` | Tolerations for nodes that have taints on them. (Optional) Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | -| topologySpreadConstraints | string | `nil` | | -| updateStrategy | object | `{}` | | +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | string | `nil` | | +| args | list | `[]` | | +| autoUpdate.image | object | `{"pullPolicy":"Always","repository":"us-docker.pkg.dev/spotit-today/container-labs/auto-updater","tag":"latest"}` | Configures the image for the auto-updater job. (Optional) | +| autoUpdate.image.pullPolicy | string | `"Always"` | Image pull policy. (Optional) | +| autoUpdate.image.repository | string | `"us-docker.pkg.dev/spotit-today/container-labs/auto-updater"` | Image repository. (Optional) | +| autoUpdate.image.tag | string | `"latest"` | Overrides the image tag. (Optional) | +| autoUpdate.imagePullSecrets | list | `[]` | Image pull secrets. (Optional) | +| autoUpdate.podSecurityContext | object | `{"fsGroup":1000690000,"runAsGroup":1000690000,"runAsNonRoot":true,"runAsUser":1000690000}` | Pod Security Context for the auto-updater job. (Optional) Ref: https://kubernetes.io/docs/concepts/security/pod-security-standards/ | +| autoUpdate.priorityClassName | string | `"system-cluster-critical"` | Priority class name for the auto-updater job. Defaults to the same priority class as the controller to prevent eviction. (Optional) | +| autoUpdate.resources | object | `{"limits":{"cpu":"100m","memory":"256Mi"},"requests":{"cpu":"100m","memory":"256Mi"}}` | Resource requests and limits for the auto-updater job. Defaults to 100m CPU and 256Mi memory to make the job run with 'Guranteed' QoS. (Optional) | +| autoUpdate.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}` | Security Context for the auto-updater container. (Optional) | +| autoUpdate.serviceAccount.annotations | object | `{}` | | +| autoUpdate.serviceAccount.create | bool | `true` | | +| autoUpdate.serviceAccount.name | string | `""` | | +| caBundleSecret.create | bool | `false` | Controls whether a CA bundle secret should be created. | +| caBundleSecret.data | string | `""` | Must contain the CA bundle data in case `caBundleSecret.create` is true. For example by using `--set caBundleSecret.data="$(cat ./ca.pem)"` | +| caBundleSecret.key | string | `"userEnvCertificates.pem"` | Key inside the secret to inject the CA bundle from | +| caBundleSecret.name | string | `""` | CA bundle Secret name. (Optional) | +| command | list | `[]` | | +| commonLabels | object | `{}` | | +| configMap.create | bool | `true` | | +| configMap.name | string | `""` | ConfigMap name. (Optional) | +| deploymentAnnotations | object | `{}` | | +| extraEnv | list | `[]` | | +| extraVolumeMounts | list | `[]` | | +| extraVolumes | list | `[]` | | +| fullnameOverride | string | `""` | | +| image.fips | bool | `false` | Set to `true` to use an FIPS-140 compliant image. This flag adds `-fips` suffix to the image tag, therefore it should not be used together with the `--image.tag` flag. Ref: https://go.dev/doc/security/fips140 | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"us-docker.pkg.dev/spotit-today/container-labs/spotinst-kubernetes-controller"` | | +| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | +| imagePullSecrets | list | `[]` | | +| initContainers | list | `[]` | | +| livenessProbe.httpGet.path | string | `"/healthz"` | | +| livenessProbe.httpGet.port | string | `"readiness"` | | +| livenessProbe.initialDelaySeconds | int | `15` | | +| livenessProbe.periodSeconds | int | `20` | | +| logShipping | object | `{"command":["/fluent-bit/bin/fluent-bit","-c","/tmp/fluent-bit.conf","-q"],"destination":{"host":"api.spotinst.io","port":443,"tls":true},"enabled":true,"extraEnv":[],"extraVolumeMounts":[],"image":{"pullPolicy":"IfNotPresent","repository":"ghcr.io/fluent/fluent-bit","tag":"3.1.9"},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}}` | Log Shipping configuration. | +| logShipping.command | list | `["/fluent-bit/bin/fluent-bit","-c","/tmp/fluent-bit.conf","-q"]` | Log shipping container command. (Optional) | +| logShipping.destination | object | `{"host":"api.spotinst.io","port":443,"tls":true}` | Log shipping destination configuration. | +| logShipping.enabled | bool | `true` | Specifies whether to send the controller logs to Spot for analysis. (Optional) | +| logShipping.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. (Optional) | +| logShipping.image.repository | string | `"ghcr.io/fluent/fluent-bit"` | Image repository. (Optional) | +| logShipping.image.tag | string | `"3.1.9"` | Overrides the image tag. (Optional) | +| logShipping.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}` | Log Shipping container security context | +| metrics-server.deployChart | bool | `true` | Specifies whether the metrics-server chart should be deployed. | +| metrics-server.image.pullPolicy | string | `"IfNotPresent"` | | +| metrics-server.image.repository | string | `"registry.k8s.io/metrics-server/metrics-server"` | | +| metrics-server.image.tag | string | `""` | | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| ocean-vpa.deployChart | bool | `true` | Specifies whether the ocean-vpa chart should be deployed. | +| podAnnotations | object | `{}` | | +| podLabels | object | `{}` | | +| podSecurityContext.fsGroup | int | `1000690000` | | +| podSecurityContext.runAsGroup | int | `1000690000` | | +| podSecurityContext.runAsNonRoot | bool | `true` | | +| podSecurityContext.runAsUser | int | `1000690000` | | +| priorityClassName | string | `"system-node-critical"` | Priority class name for the controller pod. | +| readinessProbe.httpGet.path | string | `"/readyz"` | | +| readinessProbe.httpGet.port | string | `"readiness"` | | +| readinessProbe.initialDelaySeconds | int | `5` | | +| readinessProbe.periodSeconds | int | `10` | | +| replicas | int | `2` | Configure the amount of replicas for the controller (Optional) | +| resourceQuota | object | `{"enabled":true}` | Resource Quota configuration. Required when running in a namespace other than kube-system in GKE. Ref: https://kubernetes.io/docs/concepts/policy/resource-quotas/ | +| resources | object | `{}` | | +| schedulerName | string | `""` | | +| secret.create | bool | `true` | Controls whether a Secret should be created. (Optional) | +| secret.name | string | `""` | Secret name. (Optional) | +| securityContext.allowPrivilegeEscalation | bool | `false` | | +| securityContext.capabilities.drop[0] | string | `"ALL"` | | +| securityContext.readOnlyRootFilesystem | bool | `true` | | +| securityContext.runAsNonRoot | bool | `true` | | +| serviceAccount.annotations | object | `{}` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `""` | | +| spotinst.account | string | `""` | Spot Account ID. (Required) Example: `act-123abcd` | +| spotinst.baseUrl | string | `""` | Base URL. (Optional) | +| spotinst.clusterIdentifier | string | `""` | Unique identifier used by the Ocean Controller to connect (Required) between the Ocean backend and the Kubernetes cluster. Ref: https://docs.spot.io/ocean/tutorials/spot-kubernetes-controller/ | +| spotinst.disableAutoUpdate | bool | `false` | Disable auto update. (Optional) | +| spotinst.enableCsrApproval | bool | `true` | Enable CSR approval. (Optional) | +| spotinst.insecureSkipTLSVerify | bool | `false` | Disable TLS certificate validation. (Optional) | +| spotinst.proxyUrl | string | `""` | Proxy URL. (Optional) | +| spotinst.readonly | bool | `true` | Whether this controller needs to be readonly - overrides other permissions. (Optional) | +| spotinst.token | string | `""` | Spot Token. (Required) Ref: https://docs.spot.io/administration/api/create-api-token | +| tolerations | string | `nil` | Tolerations for nodes that have taints on them. (Optional) Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ | +| topologySpreadConstraints | string | `nil` | | +| updateStrategy | object | `{}` | | ---------------------------------------------- Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) From 26927383c12d7d4aa312622c8a378d97bc9ab030 Mon Sep 17 00:00:00 2001 From: atarasov Date: Thu, 11 Sep 2025 09:49:02 +0300 Subject: [PATCH 3/3] CON-34562 - auto-update support --- .../templates/auto-update/clusterrole.yaml | 19 +++++++++++++++++++ .../templates/auto-update/role.yaml | 16 ++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/charts/ocean-right-sizing-controller/templates/auto-update/clusterrole.yaml b/charts/ocean-right-sizing-controller/templates/auto-update/clusterrole.yaml index 292133a0..1133246d 100644 --- a/charts/ocean-right-sizing-controller/templates/auto-update/clusterrole.yaml +++ b/charts/ocean-right-sizing-controller/templates/auto-update/clusterrole.yaml @@ -50,4 +50,23 @@ rules: resourceNames: - {{ printf "%s-auth-reader" (include "metrics-server.fullname" .) }} {{- end }} + +# Ocean VPA requires +{{- if (index .Values "ocean-vpa" "deployChart") }} +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterrolebindings" ] + verbs: [ "get", "patch" ] + resourceNames: + - system:vpa-updater-in-place-binding + - system:vpa-actor + - system:vpa-target-reader-binding + - system:vpa-evictioner-binding + - system:vpa-admission-controller + - vpa-status-reader-binding +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "rolebindings" ] + verbs: [ "get", "patch" ] + resourceNames: + - system:leader-locking-vpa-updater +{{- end }} {{- end }} \ No newline at end of file diff --git a/charts/ocean-right-sizing-controller/templates/auto-update/role.yaml b/charts/ocean-right-sizing-controller/templates/auto-update/role.yaml index 503056f5..a40222d1 100644 --- a/charts/ocean-right-sizing-controller/templates/auto-update/role.yaml +++ b/charts/ocean-right-sizing-controller/templates/auto-update/role.yaml @@ -79,4 +79,20 @@ rules: resourceNames: [ {{ include "metrics-server.fullname" . }} ] verbs: [ "get", "patch" ] {{- end }} + +# Ocean VPA requires +{{- if (index .Values "ocean-vpa" "deployChart") }} +- apiGroups: [ "" ] + resources: [ "serviceaccounts" ] + resourceNames: [ {{ include "ocean-vpa.serviceAccountName" . }}-admission-controller, {{ include "ocean-vpa.serviceAccountName" . }}-updater ] + verbs: [ "get", "patch" ] +- apiGroups: [ "" ] + resources: [ "services" ] + resourceNames: [ {{ include "ocean-vpa.fullname" . }}-webhook ] + verbs: [ "get", "patch" ] +- apiGroups: [ "apps" ] + resources: [ "deployments" ] + resourceNames: [ {{ include "ocean-vpa.fullname" . }}-updater, {{ include "ocean-vpa.fullname" . }}-admission-controller ] + verbs: [ "get", "patch" ] +{{- end }} {{- end }} \ No newline at end of file