From d298b905250979462e0900952d83f8793693685e Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Fri, 15 Nov 2024 17:51:05 -0700 Subject: [PATCH 01/11] Draft: adding support for proxy cache --- charts/guardrails/Chart.yaml | 2 +- charts/guardrails/README.md | 12 ++- .../guardrails/templates/configmap-cache.yaml | 63 +++++++++++++++ .../templates/deployment-cache.yaml | 76 +++++++++++++++++++ .../guardrails/templates/service-cache.yaml | 15 ++++ charts/guardrails/values.yaml | 6 ++ 6 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 charts/guardrails/templates/configmap-cache.yaml create mode 100644 charts/guardrails/templates/deployment-cache.yaml create mode 100644 charts/guardrails/templates/service-cache.yaml diff --git a/charts/guardrails/Chart.yaml b/charts/guardrails/Chart.yaml index c8a2349..4d94184 100644 --- a/charts/guardrails/Chart.yaml +++ b/charts/guardrails/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: guardrails description: A Helm chart for WhyLabs Guardrails type: application -version: 0.3.1 +version: 0.4.0 appVersion: "2.0.1" diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index 057c59d..b100f27 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -1,6 +1,6 @@ # guardrails -![Version: 0.3.1](https://img.shields.io/badge/Version-0.3.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.0.1](https://img.shields.io/badge/AppVersion-2.0.1-informational?style=flat-square) +![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.0.1](https://img.shields.io/badge/AppVersion-2.0.1-informational?style=flat-square) A Helm chart for WhyLabs Guardrails @@ -110,14 +110,14 @@ release_name="" # the working directory or --destination path helm pull \ oci://ghcr.io/whylabs/guardrails \ - --version 0.3.1 + --version 0.4.0 # Requires the helm-diff plugin to be installed: # helm plugin install https://github.com/databus23/helm-diff helm diff upgrade \ --allow-unreleased \ --namespace "${target_namespace}" \ - "${release_name}" guardrails-0.3.1.tgz + "${release_name}" guardrails-0.4.0.tgz ``` After you've installed the repo you can install the chart. @@ -126,7 +126,7 @@ After you've installed the repo you can install the chart. helm upgrade --install \ --create-namespace \ --namespace "${target_namespace}" \ - "${release_name}" guardrails-0.3.1.tgz + "${release_name}" guardrails-0.4.0.tgz ``` ## Exposing Guardrails Outside Kubernetes @@ -196,6 +196,10 @@ utilization. |-----|------|---------|-------------| | affinity | object | `{}` | Affinity settings for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). If an explicit label selector is not provided for pod affinity or pod anti-affinity one will be created from the pod selector labels. | | autoscaling | object | `{"enabled":false,"maxReplicas":100,"minReplicas":1,"targetCPUUtilizationPercentage":70}` | [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) configuration for the `guardrails` container. | +| cache.annotations | object | `{}` | | +| cache.enable | bool | `false` | | +| cache.labels | object | `{}` | | +| cache.replicaCount | int | `1` | | | commonLabels | object | `{}` | Labels to add to all chart resources. | | env | object | `{}` | [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `guardrails` container. | | envFrom | list | `[{"secretRef":{"name":"whylabs-guardrails-api-key","optional":true}},{"secretRef":{"name":"whylabs-guardrails-api-secret","optional":true}}]` | Create environment variables from Kubernetes secrets or config maps. | diff --git a/charts/guardrails/templates/configmap-cache.yaml b/charts/guardrails/templates/configmap-cache.yaml new file mode 100644 index 0000000..fb68d6c --- /dev/null +++ b/charts/guardrails/templates/configmap-cache.yaml @@ -0,0 +1,63 @@ +{{- if .Values.cache.enable }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cache +data: + nginx.conf: | + pid /tmp/nginx.pid; + events { + worker_connections 1024; + } + http { + proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=my_cache:10m max_size=1g + inactive=60m use_temp_path=off; + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp_path; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + server { + listen 8080; + server_name localhost; + location /v1/policy/list { + include cache_config.conf; + include common_proxy.conf; + proxy_cache_key "$request_uri|$http_x_whylabs_organization"; + } + location /v1/organizations/managed-organizations { + include cache_config.conf; + include common_proxy.conf; + proxy_cache_key "$request_uri|$http_x_whylabs_organization"; + } + location /v1/policy { + include cache_config.conf; + include common_proxy.conf; + proxy_cache_key "$request_uri|$http_x_whylabs_organization"; + } + location /v1/api-key/validate { + include cache_config.conf; + include common_proxy.conf; + proxy_cache_key "$request_uri|$http_x_api_key"; + } + location / { + include common_proxy.conf; + } + } + } + cache_config.conf: | + proxy_cache my_cache; + proxy_cache_valid 200 403 1m; + proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; + add_header X-Cache-Status $upstream_cache_status always; + common_proxy.conf: | + proxy_pass https://songbird.development.whylabsdev.com; + proxy_set_header Host songbird.development.whylabsdev.com; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Accept $http_accept; + proxy_set_header Accept-Encoding $http_accept_encoding; + proxy_set_header X-API-Key $http_x_api_key; + proxy_set_header X-WhyLabs-Organization $http_x_whylabs_organization; +{{- end }} diff --git a/charts/guardrails/templates/deployment-cache.yaml b/charts/guardrails/templates/deployment-cache.yaml new file mode 100644 index 0000000..c86d92d --- /dev/null +++ b/charts/guardrails/templates/deployment-cache.yaml @@ -0,0 +1,76 @@ +{{- if .Values.cache.enable }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-cache + labels: + {{- include "guardrails.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.cache.replicaCount }} + selector: + matchLabels: + app: {{ .Release.Name }}-cache + template: + metadata: + {{- with .Values.cache.annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "guardrails.labels" . | nindent 8 }} + app: {{ .Release.Name }}-cache + spec: + serviceAccountName: {{ include "guardrails.serviceAccountName" . }} + containers: + - name: nginx + securityContext: + privileged: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 101 + runAsGroup: 101 + fsGroup: 101 + capabilities: + drop: ["ALL"] + image: "nginxinc/nginx-unprivileged:latest" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - name: nginx-config + mountPath: /etc/nginx/cache_config.conf + subPath: cache_config.conf + - name: nginx-config + mountPath: /etc/nginx/common_proxy.conf + subPath: common_proxy.conf + - name: nginx-temp + mountPath: /tmp + - name: nginx-cache + mountPath: /var/cache/nginx + volumes: + - name: nginx-temp + emptyDir: {} + - name: nginx-cache + emptyDir: {} + - name: nginx-config + configMap: + name: {{ include "guardrails.fullname" . }}-cache + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/guardrails/templates/service-cache.yaml b/charts/guardrails/templates/service-cache.yaml new file mode 100644 index 0000000..4965a64 --- /dev/null +++ b/charts/guardrails/templates/service-cache.yaml @@ -0,0 +1,15 @@ +{{- if .Values.cache.enable }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-cache +spec: + type: ClusterIP + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 8080 + selector: + app: {{ .Release.Name }}-cache +{{- end }} diff --git a/charts/guardrails/values.yaml b/charts/guardrails/values.yaml index a9de091..6e90368 100644 --- a/charts/guardrails/values.yaml +++ b/charts/guardrails/values.yaml @@ -1,3 +1,9 @@ +cache: + enable: false + replicaCount: 1 + annotations: {} + labels: {} + # -- Number of replicas for the service. replicaCount: 4 From 5fe974af32276e2cbe5b1a223a8f5155cdf8922e Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Tue, 26 Nov 2024 09:37:42 -0700 Subject: [PATCH 02/11] Update default image to 2.2.2; add cache; update HPA --- charts/guardrails/CHANGELOG.md | 11 +++++ charts/guardrails/README.md | 22 +++++----- charts/guardrails/README.md.gotmpl | 16 ++++---- .../guardrails/templates/configmap-cache.yaml | 6 +-- .../templates/deployment-cache.yaml | 3 +- charts/guardrails/templates/hpa.yaml | 41 ++++++++++++++++++- charts/guardrails/values.yaml | 35 +++++++++++++++- 7 files changed, 109 insertions(+), 25 deletions(-) diff --git a/charts/guardrails/CHANGELOG.md b/charts/guardrails/CHANGELOG.md index 9105ddc..b825761 100644 --- a/charts/guardrails/CHANGELOG.md +++ b/charts/guardrails/CHANGELOG.md @@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning] (https://semver.org/spec/v2.0.0.html). +## [0.4.0] - 2024-11-26 + +### Changed + +- Default image tag from `2.0.1` to `2.2.2` + +### Added + +- Caching support enabled with `cache.enable: true` +- Horizontal Pod Autoscaler (HPA) support for configuring scaling behavior + ## [0.3.1] - 2024-10-31 ### Fixed diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index b100f27..e5f1a00 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -31,11 +31,11 @@ You can manage the API keys and container secrets in one of two ways, depending # Helm release name (See installation for release_name usage) release_name="" - kubectl create secret generic "whylabs-${release_name}-api-key" \ + kubectl create secret generic "whylabs-guardrails-api-key" \ --namespace "${target_namespace}" \ --from-literal=WHYLABS_API_KEY="${whylabs_api_key}" - kubectl create secret generic "whylabs-${release_name}-api-secret" \ + kubectl create secret generic "whylabs-guardrails-api-secret" \ --namespace "${target_namespace}" \ --from-literal=CONTAINER_PASSWORD="${container_password}" @@ -67,12 +67,12 @@ You can manage the API keys and container secrets in one of two ways, depending ```yaml envFrom: - whylabs-guardrails-api-key: - type: secretRef - optional: true - whylabs-guardrails-api-secret: - type: secretRef - optional: true + - secretRef: + name: whylabs-guardrails-api-key + optional: true + - secretRef: + name: whylabs-guardrails-api-secret + optional: true ``` - File-based Secrets: If you are using a CSI driver, set envFrom: {} in your @@ -195,9 +195,11 @@ utilization. | Key | Type | Default | Description | |-----|------|---------|-------------| | affinity | object | `{}` | Affinity settings for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). If an explicit label selector is not provided for pod affinity or pod anti-affinity one will be created from the pod selector labels. | -| autoscaling | object | `{"enabled":false,"maxReplicas":100,"minReplicas":1,"targetCPUUtilizationPercentage":70}` | [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) configuration for the `guardrails` container. | +| autoscaling | object | `{"behavior":{"scaleDown":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":30}],"selectPolicy":"Max","stabilizationWindowSeconds":300},"scaleUp":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":50}],"selectPolicy":"Min","stabilizationWindowSeconds":180}},"enabled":false,"maxReplicas":100,"minReplicas":1,"targetCPUUtilizationPercentage":70}` | [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) configuration for the `guardrails` container. | | cache.annotations | object | `{}` | | +| cache.duration | string | `"1m"` | | | cache.enable | bool | `false` | | +| cache.endpoint | string | `"api.whylabsapp.com"` | | | cache.labels | object | `{}` | | | cache.replicaCount | int | `1` | | | commonLabels | object | `{}` | Labels to add to all chart resources. | @@ -208,7 +210,7 @@ utilization. | fullnameOverride | string | `""` | Override the full name of the chart. | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy for the `guardrails` container. | | image.repository | string | `"registry.gitlab.com/whylabs/langkit-container"` | Image repository for the `guardrails` container. | -| image.tag | string | `""` | Image tag for the `guardrails` container, this will default to `.Chart.AppVersion` if not set. | +| image.tag | string | `"2.2.2"` | Image tag for the `guardrails` container, this will default to `.Chart.AppVersion` if not set. | | imagePullSecrets[0] | list | `{"name":""}` | Image pull secrets for the `guardrails` container. Defaults to `whylabs-{{ .Release.Name }}-registry-credentials` if `name: ""`. To exclude The ImagePullSecret entirely, set `imagePullSecrets: []` and comment out the list items. | | ingress | object | `{"annotations":{},"className":"","enabled":false,"hosts":[{"host":"chart-example.local","paths":[{"path":"/","pathType":"ImplementationSpecific"}]}],"tls":[]}` | [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) configuration for the `guardrails` container. | | livenessProbe | object | `{"failureThreshold":3,"httpGet":{"path":"/health","port":8000},"initialDelaySeconds":30,"periodSeconds":30}` | [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. | diff --git a/charts/guardrails/README.md.gotmpl b/charts/guardrails/README.md.gotmpl index 1f76c99..61778f2 100644 --- a/charts/guardrails/README.md.gotmpl +++ b/charts/guardrails/README.md.gotmpl @@ -38,11 +38,11 @@ You can manage the API keys and container secrets in one of two ways, depending # Helm release name (See installation for release_name usage) release_name="" - kubectl create secret generic "whylabs-${release_name}-api-key" \ + kubectl create secret generic "whylabs-guardrails-api-key" \ --namespace "${target_namespace}" \ --from-literal=WHYLABS_API_KEY="${whylabs_api_key}" - kubectl create secret generic "whylabs-${release_name}-api-secret" \ + kubectl create secret generic "whylabs-guardrails-api-secret" \ --namespace "${target_namespace}" \ --from-literal=CONTAINER_PASSWORD="${container_password}" @@ -74,12 +74,12 @@ You can manage the API keys and container secrets in one of two ways, depending ```yaml envFrom: - whylabs-guardrails-api-key: - type: secretRef - optional: true - whylabs-guardrails-api-secret: - type: secretRef - optional: true + - secretRef: + name: whylabs-guardrails-api-key + optional: true + - secretRef: + name: whylabs-guardrails-api-secret + optional: true ``` - File-based Secrets: If you are using a CSI driver, set envFrom: {} in your diff --git a/charts/guardrails/templates/configmap-cache.yaml b/charts/guardrails/templates/configmap-cache.yaml index fb68d6c..d649e30 100644 --- a/charts/guardrails/templates/configmap-cache.yaml +++ b/charts/guardrails/templates/configmap-cache.yaml @@ -47,12 +47,12 @@ data: } cache_config.conf: | proxy_cache my_cache; - proxy_cache_valid 200 403 1m; + proxy_cache_valid 200 403 {{ .Values.cache.duration }}; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; add_header X-Cache-Status $upstream_cache_status always; common_proxy.conf: | - proxy_pass https://songbird.development.whylabsdev.com; - proxy_set_header Host songbird.development.whylabsdev.com; + proxy_pass https://{{ .Values.cache.endpoint }}; + proxy_set_header Host {{ .Values.cache.endpoint }}; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; diff --git a/charts/guardrails/templates/deployment-cache.yaml b/charts/guardrails/templates/deployment-cache.yaml index c86d92d..f4d5f2c 100644 --- a/charts/guardrails/templates/deployment-cache.yaml +++ b/charts/guardrails/templates/deployment-cache.yaml @@ -21,6 +21,8 @@ spec: app: {{ .Release.Name }}-cache spec: serviceAccountName: {{ include "guardrails.serviceAccountName" . }} + securityContext: + fsGroup: 101 containers: - name: nginx securityContext: @@ -30,7 +32,6 @@ spec: runAsNonRoot: true runAsUser: 101 runAsGroup: 101 - fsGroup: 101 capabilities: drop: ["ALL"] image: "nginxinc/nginx-unprivileged:latest" diff --git a/charts/guardrails/templates/hpa.yaml b/charts/guardrails/templates/hpa.yaml index 5635c08..fd3b6c2 100644 --- a/charts/guardrails/templates/hpa.yaml +++ b/charts/guardrails/templates/hpa.yaml @@ -10,8 +10,45 @@ spec: apiVersion: apps/v1 kind: Deployment name: {{ include "guardrails.fullname" . }} - minReplicas: {{ .Values.autoscaling.minReplicas }} - maxReplicas: {{ .Values.autoscaling.maxReplicas }} + minReplicas: {{ default 1 .Values.autoscaling.minReplicas }} + maxReplicas: {{ default 20 .Values.autoscaling.maxReplicas }} + {{- with .Values.autoscaling.behavior }} + behavior: + {{- with .scaleUp }} + scaleUp: + {{- with .policies }} + policies: + {{- range . }} + - type: {{ .type }} + value: {{ tpl (toString .value) $ | int }} + periodSeconds: {{ .periodSeconds | int }} + {{- end }} + {{- end }} + {{- with .selectPolicy }} + selectPolicy: {{ . }} + {{- end }} + {{- with .stabilizationWindowSeconds }} + stabilizationWindowSeconds: {{ . | int }} + {{- end }} + {{- end }} + {{- with .scaleDown }} + scaleDown: + {{- with .policies }} + policies: + {{- range . }} + - type: {{ .type }} + value: {{ tpl (toString .value) $ | int }} + periodSeconds: {{ .periodSeconds | int }} + {{- end }} + {{- end }} + {{- with .selectPolicy }} + selectPolicy: {{ . }} + {{- end }} + {{- with .stabilizationWindowSeconds }} + stabilizationWindowSeconds: {{ . | int}} + {{- end }} + {{- end }} + {{- end }} metrics: {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} - type: Resource diff --git a/charts/guardrails/values.yaml b/charts/guardrails/values.yaml index 6e90368..9d1d6c8 100644 --- a/charts/guardrails/values.yaml +++ b/charts/guardrails/values.yaml @@ -1,6 +1,8 @@ cache: enable: false + duration: 1m replicaCount: 1 + endpoint: "api.whylabsapp.com" annotations: {} labels: {} @@ -14,7 +16,7 @@ image: pullPolicy: IfNotPresent # -- (string) Image tag for the `guardrails` container, this will default to # `.Chart.AppVersion` if not set. - tag: "" + tag: "2.2.2" imagePullSecrets: # -- (list) Image pull secrets for the `guardrails` container. Defaults to @@ -138,6 +140,37 @@ autoscaling: enabled: false minReplicas: 1 maxReplicas: 100 + behavior: + scaleUp: + policies: + - type: Pods + value: "{{ .Values.replicaCount | int }}" + periodSeconds: 180 + - type: Percent + value: 50 + periodSeconds: 180 + # selectPolicy can be `Min` or `Max` and refers to scaling policy + # to choose when there are multiple policies; `Max` will choose the + # policy perform the largest scaling adjustment, while `Min` will + # choose the policy that performs the smallest scaling adjustment. + selectPolicy: Min + stabilizationWindowSeconds: 180 + scaleDown: + policies: + - type: Pods + value: "{{ .Values.replicaCount | int }}" + # periodSeconds is the rate at which a policy can be applied; + # this policy may only be applied once per period. + periodSeconds: 180 + - type: Percent + value: 30 + # periodSeconds is the rate at which a policy can be applied; + # this policy may only be applied once per period. + periodSeconds: 180 + selectPolicy: Max + # stabilizationWindowSeconds is how many seconds the HPA looks back + # to determine if a policy is being met. + stabilizationWindowSeconds: 300 targetCPUUtilizationPercentage: 70 # targetMemoryUtilizationPercentage: 70 From a47fd06d21f1e6707dc3cb44d506e6fa525fcf68 Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Tue, 26 Nov 2024 10:11:31 -0700 Subject: [PATCH 03/11] additional updates --- charts/guardrails/CHANGELOG.md | 1 + charts/guardrails/README.md | 5 +++-- charts/guardrails/templates/deployment.yaml | 2 ++ charts/guardrails/values.yaml | 23 ++++++++++++++------- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/charts/guardrails/CHANGELOG.md b/charts/guardrails/CHANGELOG.md index b825761..b64f7be 100644 --- a/charts/guardrails/CHANGELOG.md +++ b/charts/guardrails/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning] - Caching support enabled with `cache.enable: true` - Horizontal Pod Autoscaler (HPA) support for configuring scaling behavior +- Startup probe to support more graceful startup and scaling behavior ## [0.3.1] - 2024-10-31 diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index e5f1a00..a101602 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -213,13 +213,13 @@ utilization. | image.tag | string | `"2.2.2"` | Image tag for the `guardrails` container, this will default to `.Chart.AppVersion` if not set. | | imagePullSecrets[0] | list | `{"name":""}` | Image pull secrets for the `guardrails` container. Defaults to `whylabs-{{ .Release.Name }}-registry-credentials` if `name: ""`. To exclude The ImagePullSecret entirely, set `imagePullSecrets: []` and comment out the list items. | | ingress | object | `{"annotations":{},"className":"","enabled":false,"hosts":[{"host":"chart-example.local","paths":[{"path":"/","pathType":"ImplementationSpecific"}]}],"tls":[]}` | [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) configuration for the `guardrails` container. | -| livenessProbe | object | `{"failureThreshold":3,"httpGet":{"path":"/health","port":8000},"initialDelaySeconds":30,"periodSeconds":30}` | [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. | +| livenessProbe | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":8000},"periodSeconds":10}` | [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Failed livenessProbes restarts containers | | nameOverride | string | `""` | Override the name of the chart. | | nodeSelector | object | `{}` | Node labels to match for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). | | podAnnotations | object | `{}` | Annotations to add to the `Pod`. | | podLabels | object | `{}` | Labels to add to the `Pod`. | | podSecurityContext | object | `{"runAsNonRoot":true}` | [Pod security context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core), this supports full customisation. | -| readinessProbe | object | `{"failureThreshold":10,"httpGet":{"path":"/health","port":8000},"initialDelaySeconds":30,"periodSeconds":30}` | [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. | +| readinessProbe | object | `{"failureThreshold":2,"httpGet":{"path":"/health","port":8000},"periodSeconds":10}` | [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Failed readinessProbes remove the pod from the service. | | replicaCount | int | `4` | Number of replicas for the service. | | resources | object | `{"limits":{"cpu":"4","ephemeral-storage":"250Mi","memory":"4Gi"},"requests":{"cpu":"4","ephemeral-storage":"250Mi","memory":"4Gi"}}` | [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `guardrails` container. | | securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsNonRoot":true,"runAsUser":1000}` | [Security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) for the `guardrails` container. | @@ -232,6 +232,7 @@ utilization. | serviceAccount.create | bool | `true` | If `true`, create a new `ServiceAccount`. | | serviceAccount.labels | object | `{}` | Labels to add to the service account. | | serviceAccount.name | string | `""` | If this is set and `serviceAccount.create` is `true` this will be used for the created `ServiceAccount` name, if set and `serviceAccount.create` is `false` then this will define an existing `ServiceAccount` to use. | +| startupProbe | object | `{"failureThreshold":20,"httpGet":{"path":"/health","port":8000},"initialDelaySeconds":20,"periodSeconds":10}` | [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Liveness and readiness probes are suppressed until the startup probe succeeds. | | tolerations | list | `[]` | Node taints which will be tolerated for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). | ---------------------------------------------- diff --git a/charts/guardrails/templates/deployment.yaml b/charts/guardrails/templates/deployment.yaml index 55d65af..56e8259 100644 --- a/charts/guardrails/templates/deployment.yaml +++ b/charts/guardrails/templates/deployment.yaml @@ -62,6 +62,8 @@ spec: {{- toYaml .Values.livenessProbe | nindent 12 }} readinessProbe: {{- toYaml .Values.readinessProbe | nindent 12 }} + startupProbe: + {{- toYaml .Values.startupProbe | nindent 12 }} resources: {{- toYaml .Values.resources | nindent 12 }} volumeMounts: diff --git a/charts/guardrails/values.yaml b/charts/guardrails/values.yaml index 9d1d6c8..14e56b2 100644 --- a/charts/guardrails/values.yaml +++ b/charts/guardrails/values.yaml @@ -117,23 +117,30 @@ resources: memory: 4Gi ephemeral-storage: 250Mi -# -- [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. +# -- [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Liveness and readiness probes are suppressed until the startup probe succeeds. +startupProbe: + httpGet: + path: /health + port: 8000 + failureThreshold: 20 + initialDelaySeconds: 20 + periodSeconds: 10 + +# -- [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Failed livenessProbes restarts containers livenessProbe: httpGet: path: /health port: 8000 - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 30 + failureThreshold: 5 + periodSeconds: 10 -# -- [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. +# -- [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Failed readinessProbes remove the pod from the service. readinessProbe: httpGet: path: /health port: 8000 - failureThreshold: 10 - initialDelaySeconds: 30 - periodSeconds: 30 + failureThreshold: 2 + periodSeconds: 10 # -- [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) configuration for the `guardrails` container. autoscaling: From 9ffa248a8f4d56657843a7ee5599addc1bc9ccc8 Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Tue, 26 Nov 2024 10:16:46 -0700 Subject: [PATCH 04/11] Add icon to pass lint --- charts/guardrails/Chart.yaml | 3 ++- charts/guardrails/README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/charts/guardrails/Chart.yaml b/charts/guardrails/Chart.yaml index 4d94184..4500adc 100644 --- a/charts/guardrails/Chart.yaml +++ b/charts/guardrails/Chart.yaml @@ -3,4 +3,5 @@ name: guardrails description: A Helm chart for WhyLabs Guardrails type: application version: 0.4.0 -appVersion: "2.0.1" +appVersion: "2.2.2" +icon: "https://whylabs.ai/_next/static/images/whylabs-favicon-192c009321aebbb96c19921a170fc880.png" diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index a101602..6c7e974 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -1,6 +1,6 @@ # guardrails -![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.0.1](https://img.shields.io/badge/AppVersion-2.0.1-informational?style=flat-square) +![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.2.2](https://img.shields.io/badge/AppVersion-2.2.2-informational?style=flat-square) A Helm chart for WhyLabs Guardrails From 9d524c01b8ed97931149c1c959f4dc17305caddb Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Tue, 26 Nov 2024 10:47:10 -0700 Subject: [PATCH 05/11] remove readonly root file system of nginx pod --- charts/guardrails/templates/deployment-cache.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/charts/guardrails/templates/deployment-cache.yaml b/charts/guardrails/templates/deployment-cache.yaml index f4d5f2c..309b2f0 100644 --- a/charts/guardrails/templates/deployment-cache.yaml +++ b/charts/guardrails/templates/deployment-cache.yaml @@ -28,7 +28,6 @@ spec: securityContext: privileged: false allowPrivilegeEscalation: false - readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 101 runAsGroup: 101 From de2f9fced4b0d4c07dea0f89943cf6b42123b9c5 Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Mon, 2 Dec 2024 13:56:20 -0700 Subject: [PATCH 06/11] Update selector labels --- charts/guardrails/templates/_helpers.tpl | 1 - charts/guardrails/templates/configmap-cache.yaml | 2 +- charts/guardrails/templates/deployment-cache.yaml | 6 +++--- charts/guardrails/templates/deployment.yaml | 3 ++- charts/guardrails/templates/service-cache.yaml | 4 ++-- charts/guardrails/templates/service.yaml | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/charts/guardrails/templates/_helpers.tpl b/charts/guardrails/templates/_helpers.tpl index 2bfeb80..94d31ad 100644 --- a/charts/guardrails/templates/_helpers.tpl +++ b/charts/guardrails/templates/_helpers.tpl @@ -35,7 +35,6 @@ Common labels */}} {{- define "guardrails.labels" -}} helm.sh/chart: {{ include "guardrails.chart" . }} -{{ include "guardrails.selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} diff --git a/charts/guardrails/templates/configmap-cache.yaml b/charts/guardrails/templates/configmap-cache.yaml index d649e30..4090d31 100644 --- a/charts/guardrails/templates/configmap-cache.yaml +++ b/charts/guardrails/templates/configmap-cache.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ .Release.Name }}-cache + name: {{ .Release.Name }}-nginx data: nginx.conf: | pid /tmp/nginx.pid; diff --git a/charts/guardrails/templates/deployment-cache.yaml b/charts/guardrails/templates/deployment-cache.yaml index 309b2f0..6b4cfff 100644 --- a/charts/guardrails/templates/deployment-cache.yaml +++ b/charts/guardrails/templates/deployment-cache.yaml @@ -2,14 +2,14 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ .Release.Name }}-cache + name: {{ .Release.Name }}-nginx labels: {{- include "guardrails.labels" . | nindent 4 }} spec: replicas: {{ .Values.cache.replicaCount }} selector: matchLabels: - app: {{ .Release.Name }}-cache + app: {{ .Release.Name }}-nginx template: metadata: {{- with .Values.cache.annotations }} @@ -18,7 +18,7 @@ spec: {{- end }} labels: {{- include "guardrails.labels" . | nindent 8 }} - app: {{ .Release.Name }}-cache + app: {{ .Release.Name }}-nginx spec: serviceAccountName: {{ include "guardrails.serviceAccountName" . }} securityContext: diff --git a/charts/guardrails/templates/deployment.yaml b/charts/guardrails/templates/deployment.yaml index 56e8259..c1be3c0 100644 --- a/charts/guardrails/templates/deployment.yaml +++ b/charts/guardrails/templates/deployment.yaml @@ -11,7 +11,7 @@ spec: {{- end }} selector: matchLabels: - {{- include "guardrails.selectorLabels" . | nindent 6 }} + app: {{ .Release.Name }} template: metadata: {{- with .Values.podAnnotations }} @@ -23,6 +23,7 @@ spec: {{- with .Values.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} + app: {{ .Release.Name }} spec: {{- if gt (len .Values.imagePullSecrets) 0 }} imagePullSecrets: diff --git a/charts/guardrails/templates/service-cache.yaml b/charts/guardrails/templates/service-cache.yaml index 4965a64..d6a835e 100644 --- a/charts/guardrails/templates/service-cache.yaml +++ b/charts/guardrails/templates/service-cache.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: - name: {{ .Release.Name }}-cache + name: {{ .Release.Name }}-nginx spec: type: ClusterIP ports: @@ -11,5 +11,5 @@ spec: port: 80 targetPort: 8080 selector: - app: {{ .Release.Name }}-cache + app: {{ .Release.Name }}-nginx {{- end }} diff --git a/charts/guardrails/templates/service.yaml b/charts/guardrails/templates/service.yaml index 085fe64..cfd0f73 100644 --- a/charts/guardrails/templates/service.yaml +++ b/charts/guardrails/templates/service.yaml @@ -16,4 +16,4 @@ spec: port: {{ .Values.service.port }} targetPort: {{ .Values.service.targetPort }} selector: - {{- include "guardrails.selectorLabels" . | nindent 4 }} + app: {{ .Release.Name }} From 8ea8aff30bd2787c332f61b27a0fc081f6524ddc Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Mon, 2 Dec 2024 13:57:45 -0700 Subject: [PATCH 07/11] bump version --- charts/guardrails/Chart.yaml | 2 +- charts/guardrails/README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/charts/guardrails/Chart.yaml b/charts/guardrails/Chart.yaml index 4500adc..55347eb 100644 --- a/charts/guardrails/Chart.yaml +++ b/charts/guardrails/Chart.yaml @@ -2,6 +2,6 @@ apiVersion: v2 name: guardrails description: A Helm chart for WhyLabs Guardrails type: application -version: 0.4.0 +version: 0.4.5 appVersion: "2.2.2" icon: "https://whylabs.ai/_next/static/images/whylabs-favicon-192c009321aebbb96c19921a170fc880.png" diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index 6c7e974..7502eff 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -1,6 +1,6 @@ # guardrails -![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.2.2](https://img.shields.io/badge/AppVersion-2.2.2-informational?style=flat-square) +![Version: 0.4.5](https://img.shields.io/badge/Version-0.4.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.2.2](https://img.shields.io/badge/AppVersion-2.2.2-informational?style=flat-square) A Helm chart for WhyLabs Guardrails @@ -110,14 +110,14 @@ release_name="" # the working directory or --destination path helm pull \ oci://ghcr.io/whylabs/guardrails \ - --version 0.4.0 + --version 0.4.5 # Requires the helm-diff plugin to be installed: # helm plugin install https://github.com/databus23/helm-diff helm diff upgrade \ --allow-unreleased \ --namespace "${target_namespace}" \ - "${release_name}" guardrails-0.4.0.tgz + "${release_name}" guardrails-0.4.5.tgz ``` After you've installed the repo you can install the chart. @@ -126,7 +126,7 @@ After you've installed the repo you can install the chart. helm upgrade --install \ --create-namespace \ --namespace "${target_namespace}" \ - "${release_name}" guardrails-0.4.0.tgz + "${release_name}" guardrails-0.4.5.tgz ``` ## Exposing Guardrails Outside Kubernetes From adab9de4564574d61160aaf7d40e4e9170492427 Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Mon, 2 Dec 2024 14:12:03 -0700 Subject: [PATCH 08/11] fix names --- charts/guardrails/Chart.yaml | 2 +- charts/guardrails/README.md | 8 ++++---- charts/guardrails/templates/deployment-cache.yaml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/charts/guardrails/Chart.yaml b/charts/guardrails/Chart.yaml index 55347eb..5be109d 100644 --- a/charts/guardrails/Chart.yaml +++ b/charts/guardrails/Chart.yaml @@ -2,6 +2,6 @@ apiVersion: v2 name: guardrails description: A Helm chart for WhyLabs Guardrails type: application -version: 0.4.5 +version: 0.4.6 appVersion: "2.2.2" icon: "https://whylabs.ai/_next/static/images/whylabs-favicon-192c009321aebbb96c19921a170fc880.png" diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index 7502eff..47c257e 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -1,6 +1,6 @@ # guardrails -![Version: 0.4.5](https://img.shields.io/badge/Version-0.4.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.2.2](https://img.shields.io/badge/AppVersion-2.2.2-informational?style=flat-square) +![Version: 0.4.6](https://img.shields.io/badge/Version-0.4.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.2.2](https://img.shields.io/badge/AppVersion-2.2.2-informational?style=flat-square) A Helm chart for WhyLabs Guardrails @@ -110,14 +110,14 @@ release_name="" # the working directory or --destination path helm pull \ oci://ghcr.io/whylabs/guardrails \ - --version 0.4.5 + --version 0.4.6 # Requires the helm-diff plugin to be installed: # helm plugin install https://github.com/databus23/helm-diff helm diff upgrade \ --allow-unreleased \ --namespace "${target_namespace}" \ - "${release_name}" guardrails-0.4.5.tgz + "${release_name}" guardrails-0.4.6.tgz ``` After you've installed the repo you can install the chart. @@ -126,7 +126,7 @@ After you've installed the repo you can install the chart. helm upgrade --install \ --create-namespace \ --namespace "${target_namespace}" \ - "${release_name}" guardrails-0.4.5.tgz + "${release_name}" guardrails-0.4.6.tgz ``` ## Exposing Guardrails Outside Kubernetes diff --git a/charts/guardrails/templates/deployment-cache.yaml b/charts/guardrails/templates/deployment-cache.yaml index 6b4cfff..929928b 100644 --- a/charts/guardrails/templates/deployment-cache.yaml +++ b/charts/guardrails/templates/deployment-cache.yaml @@ -60,7 +60,7 @@ spec: emptyDir: {} - name: nginx-config configMap: - name: {{ include "guardrails.fullname" . }}-cache + name: {{ include "guardrails.fullname" . }}-nginx {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} From 999d9d863a2c513f6c466425cdb5c5d6fafe21e9 Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Mon, 2 Dec 2024 17:03:22 -0700 Subject: [PATCH 09/11] updates --- charts/guardrails/CHANGELOG.md | 7 ++++ charts/guardrails/Chart.yaml | 2 +- charts/guardrails/README.md | 31 +++++++++++------- ...figmap-cache.yaml => configmap-nginx.yaml} | 0 ...yment-cache.yaml => deployment-nginx.yaml} | 2 ++ charts/guardrails/templates/deployment.yaml | 4 ++- ...{service-cache.yaml => service-nginx.yaml} | 0 charts/guardrails/values.yaml | 32 ++++++++++++++++--- 8 files changed, 60 insertions(+), 18 deletions(-) rename charts/guardrails/templates/{configmap-cache.yaml => configmap-nginx.yaml} (100%) rename charts/guardrails/templates/{deployment-cache.yaml => deployment-nginx.yaml} (94%) rename charts/guardrails/templates/{service-cache.yaml => service-nginx.yaml} (100%) diff --git a/charts/guardrails/CHANGELOG.md b/charts/guardrails/CHANGELOG.md index b64f7be..2e4a4f5 100644 --- a/charts/guardrails/CHANGELOG.md +++ b/charts/guardrails/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning] (https://semver.org/spec/v2.0.0.html). +## [0.5.0] - 2024-12-02 + +### Added + +- Add caching support, enabled with `cache.enable: true` (default is `true`) +- HPA support for configuring scaling behavior + ## [0.4.0] - 2024-11-26 ### Changed diff --git a/charts/guardrails/Chart.yaml b/charts/guardrails/Chart.yaml index 5be109d..1087259 100644 --- a/charts/guardrails/Chart.yaml +++ b/charts/guardrails/Chart.yaml @@ -2,6 +2,6 @@ apiVersion: v2 name: guardrails description: A Helm chart for WhyLabs Guardrails type: application -version: 0.4.6 +version: 0.5.0 appVersion: "2.2.2" icon: "https://whylabs.ai/_next/static/images/whylabs-favicon-192c009321aebbb96c19921a170fc880.png" diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index 47c257e..bf40563 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -1,6 +1,6 @@ # guardrails -![Version: 0.4.6](https://img.shields.io/badge/Version-0.4.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.2.2](https://img.shields.io/badge/AppVersion-2.2.2-informational?style=flat-square) +![Version: 0.5.0](https://img.shields.io/badge/Version-0.5.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.2.2](https://img.shields.io/badge/AppVersion-2.2.2-informational?style=flat-square) A Helm chart for WhyLabs Guardrails @@ -110,14 +110,14 @@ release_name="" # the working directory or --destination path helm pull \ oci://ghcr.io/whylabs/guardrails \ - --version 0.4.6 + --version 0.5.0 # Requires the helm-diff plugin to be installed: # helm plugin install https://github.com/databus23/helm-diff helm diff upgrade \ --allow-unreleased \ --namespace "${target_namespace}" \ - "${release_name}" guardrails-0.4.6.tgz + "${release_name}" guardrails-0.5.0.tgz ``` After you've installed the repo you can install the chart. @@ -126,7 +126,7 @@ After you've installed the repo you can install the chart. helm upgrade --install \ --create-namespace \ --namespace "${target_namespace}" \ - "${release_name}" guardrails-0.4.6.tgz + "${release_name}" guardrails-0.5.0.tgz ``` ## Exposing Guardrails Outside Kubernetes @@ -196,14 +196,22 @@ utilization. |-----|------|---------|-------------| | affinity | object | `{}` | Affinity settings for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). If an explicit label selector is not provided for pod affinity or pod anti-affinity one will be created from the pod selector labels. | | autoscaling | object | `{"behavior":{"scaleDown":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":30}],"selectPolicy":"Max","stabilizationWindowSeconds":300},"scaleUp":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":50}],"selectPolicy":"Min","stabilizationWindowSeconds":180}},"enabled":false,"maxReplicas":100,"minReplicas":1,"targetCPUUtilizationPercentage":70}` | [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) configuration for the `guardrails` container. | -| cache.annotations | object | `{}` | | -| cache.duration | string | `"1m"` | | -| cache.enable | bool | `false` | | -| cache.endpoint | string | `"api.whylabsapp.com"` | | -| cache.labels | object | `{}` | | -| cache.replicaCount | int | `1` | | +| autoscaling.behavior | object | `{"scaleDown":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":30}],"selectPolicy":"Max","stabilizationWindowSeconds":300},"scaleUp":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":50}],"selectPolicy":"Min","stabilizationWindowSeconds":180}}` | Configures the scaling behavior of the target in both Up and Downdirections | +| autoscaling.behavior.scaleDown.policies | list | `[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":30}]` | Policies a list of potential scaling polices which can be used during scaling. At least one policy must be specified. | +| autoscaling.behavior.scaleDown.selectPolicy | string | `"Max"` | selectPolicy can be `Min` or `Max` and refers to scaling policy to choose when there are multiple policies; `Max` will choose the policy perform the largest scaling adjustment, while `Min` will choose the policy that performs the smallest scaling adjustment. | +| autoscaling.behavior.scaleDown.stabilizationWindowSeconds | int | `300` | StabilizationWindowSeconds is how many seconds the HPA looks back to determine if a policy is being met. | +| autoscaling.behavior.scaleUp.policies | list | `[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":50}]` | Policies a list of potential scaling polices which can be used during scaling. At least one policy must be specified. | +| autoscaling.behavior.scaleUp.selectPolicy | string | `"Min"` | selectPolicy can be `Min` or `Max` and refers to scaling policy to choose when there are multiple policies; `Max` will choose the policy perform the largest scaling adjustment, while `Min` will choose the policy that performs the smallest scaling adjustment. | +| autoscaling.behavior.scaleUp.stabilizationWindowSeconds | int | `180` | StabilizationWindowSeconds is how many seconds the HPA looks back to determine if a policy is being met. | +| autoscaling.enabled | bool | `false` | Enable or disable HPA (Horizontal Pod Autoscaler). | +| cache.annotations | object | `{}` | Annotations for the cache. | +| cache.duration | string | `"1m"` | Duration for cache validity. | +| cache.enable | bool | `true` | Enable or disable caching. | +| cache.endpoint | string | `"api.whylabsapp.com"` | Endpoint for the cache service. | +| cache.labels | object | `{}` | Labels for the cache. | +| cache.replicaCount | int | `1` | Number of replicas for the cache. | | commonLabels | object | `{}` | Labels to add to all chart resources. | -| env | object | `{}` | [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `guardrails` container. | +| env | object | `{"TENANCY_MODE":"{{ .Values.tenancyMode | default \"SINGLE\" }}"}` | [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `guardrails` container. | | envFrom | list | `[{"secretRef":{"name":"whylabs-guardrails-api-key","optional":true}},{"secretRef":{"name":"whylabs-guardrails-api-secret","optional":true}}]` | Create environment variables from Kubernetes secrets or config maps. | | extraVolumeMounts | list | `[]` | Extra [volume mounts](https://kubernetes.io/docs/concepts/storage/volumes/) for the `guardrails` container. | | extraVolumes | list | `[]` | Extra [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) for the `Pod`. | @@ -233,6 +241,7 @@ utilization. | serviceAccount.labels | object | `{}` | Labels to add to the service account. | | serviceAccount.name | string | `""` | If this is set and `serviceAccount.create` is `true` this will be used for the created `ServiceAccount` name, if set and `serviceAccount.create` is `false` then this will define an existing `ServiceAccount` to use. | | startupProbe | object | `{"failureThreshold":20,"httpGet":{"path":"/health","port":8000},"initialDelaySeconds":20,"periodSeconds":10}` | [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Liveness and readiness probes are suppressed until the startup probe succeeds. | +| tenancyMode | string | `"MULTI"` | tenancyMode for the guardrails service. Must be `SINGLE` or `MULTI`. | | tolerations | list | `[]` | Node taints which will be tolerated for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). | ---------------------------------------------- diff --git a/charts/guardrails/templates/configmap-cache.yaml b/charts/guardrails/templates/configmap-nginx.yaml similarity index 100% rename from charts/guardrails/templates/configmap-cache.yaml rename to charts/guardrails/templates/configmap-nginx.yaml diff --git a/charts/guardrails/templates/deployment-cache.yaml b/charts/guardrails/templates/deployment-nginx.yaml similarity index 94% rename from charts/guardrails/templates/deployment-cache.yaml rename to charts/guardrails/templates/deployment-nginx.yaml index 929928b..450a3a6 100644 --- a/charts/guardrails/templates/deployment-cache.yaml +++ b/charts/guardrails/templates/deployment-nginx.yaml @@ -19,6 +19,8 @@ spec: labels: {{- include "guardrails.labels" . | nindent 8 }} app: {{ .Release.Name }}-nginx + app.kubernetes.io/name: {{ include "guardrails.name" . }}-nginx + app.kubernetes.io/instance: {{ .Release.Name }}-nginx spec: serviceAccountName: {{ include "guardrails.serviceAccountName" . }} securityContext: diff --git a/charts/guardrails/templates/deployment.yaml b/charts/guardrails/templates/deployment.yaml index c1be3c0..d1760f4 100644 --- a/charts/guardrails/templates/deployment.yaml +++ b/charts/guardrails/templates/deployment.yaml @@ -24,6 +24,8 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} app: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "guardrails.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} spec: {{- if gt (len .Values.imagePullSecrets) 0 }} imagePullSecrets: @@ -48,7 +50,7 @@ spec: env: {{- range $key, $value := .Values.env }} - name: {{ $key }} - value: {{ $value | quote }} + value: {{ tpl $value $ }} {{- end }} {{- end }} {{- if .Values.envFrom }} diff --git a/charts/guardrails/templates/service-cache.yaml b/charts/guardrails/templates/service-nginx.yaml similarity index 100% rename from charts/guardrails/templates/service-cache.yaml rename to charts/guardrails/templates/service-nginx.yaml diff --git a/charts/guardrails/values.yaml b/charts/guardrails/values.yaml index 14e56b2..76efe6d 100644 --- a/charts/guardrails/values.yaml +++ b/charts/guardrails/values.yaml @@ -1,11 +1,21 @@ cache: - enable: false + # -- Enable or disable caching. + enable: true + # -- Duration for cache validity. duration: 1m + # -- Number of replicas for the cache. replicaCount: 1 + # -- Endpoint for the cache service. endpoint: "api.whylabsapp.com" + # -- Annotations for the cache. annotations: {} + # -- Labels for the cache. labels: {} +# -- (string) tenancyMode for the guardrails service. +# Must be `SINGLE` or `MULTI`. +tenancyMode: MULTI + # -- Number of replicas for the service. replicaCount: 4 @@ -35,8 +45,10 @@ fullnameOverride: "" commonLabels: {} # -- [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `guardrails` container. -env: {} - # MY_ENV_VAR: "my env var value" +env: + # Uncomment WHYLABS_API_CACHE_ENDPOINT if .Values.cache.enable is true + # WHYLABS_API_CACHE_ENDPOINT: "{{ .Release.Name }}.{{ .Release.Namespace }}.svc.cluster.local" + TENANCY_MODE: "{{ .Values.tenancyMode | default \"SINGLE\" }}" # -- Create environment variables from Kubernetes secrets or config maps. envFrom: @@ -144,11 +156,14 @@ readinessProbe: # -- [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) configuration for the `guardrails` container. autoscaling: + # -- Enable or disable HPA (Horizontal Pod Autoscaler). enabled: false minReplicas: 1 maxReplicas: 100 + # -- Configures the scaling behavior of the target in both Up and Downdirections behavior: scaleUp: + # -- Policies a list of potential scaling polices which can be used during scaling. At least one policy must be specified. policies: - type: Pods value: "{{ .Values.replicaCount | int }}" @@ -156,13 +171,16 @@ autoscaling: - type: Percent value: 50 periodSeconds: 180 - # selectPolicy can be `Min` or `Max` and refers to scaling policy + # -- selectPolicy can be `Min` or `Max` and refers to scaling policy # to choose when there are multiple policies; `Max` will choose the # policy perform the largest scaling adjustment, while `Min` will # choose the policy that performs the smallest scaling adjustment. selectPolicy: Min + # -- StabilizationWindowSeconds is how many seconds the HPA looks back + # to determine if a policy is being met. stabilizationWindowSeconds: 180 scaleDown: + # -- Policies a list of potential scaling polices which can be used during scaling. At least one policy must be specified. policies: - type: Pods value: "{{ .Values.replicaCount | int }}" @@ -174,8 +192,12 @@ autoscaling: # periodSeconds is the rate at which a policy can be applied; # this policy may only be applied once per period. periodSeconds: 180 + # -- selectPolicy can be `Min` or `Max` and refers to scaling policy + # to choose when there are multiple policies; `Max` will choose the + # policy perform the largest scaling adjustment, while `Min` will + # choose the policy that performs the smallest scaling adjustment. selectPolicy: Max - # stabilizationWindowSeconds is how many seconds the HPA looks back + # -- StabilizationWindowSeconds is how many seconds the HPA looks back # to determine if a policy is being met. stabilizationWindowSeconds: 300 targetCPUUtilizationPercentage: 70 From 5f7aa81e9d84bd6cab323c705d06b417043639ff Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Tue, 3 Dec 2024 10:54:00 -0700 Subject: [PATCH 10/11] updated docs --- charts/guardrails/README.md | 247 ++++++++++++++-------- charts/guardrails/README.md.gotmpl | 225 +++++++++++++------- charts/guardrails/values.yaml | 321 +++++++++++++++-------------- 3 files changed, 486 insertions(+), 307 deletions(-) diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index bf40563..ad0177f 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -4,93 +4,101 @@ A Helm chart for WhyLabs Guardrails +- [Prerequisites](#prerequisites) +- [Configuring WhyLabs credentials](#whylabs-credentials) +- [Helm Chart Installation & Upgrades](#installation-upgrades) +- [Exposing Guardrails Outside Kubernetes](#exposing-guardrails-outside-kubernetes) +- [Horizontal Pod Autoscaling (HPA)](#horizontal-pod-autoscaling-hpa) + ## Prerequisites -### API Key and Secrets Management +- [Create and configure WhyLabs credentials](#whylabs-credentials) -Create a [WhyLabs API Key](https://docs.whylabs.ai/docs/whylabs-api/#creating-an-api-token) -that will be used when creating the required Kubernetes secrets to authenticate -with the WhyLabs API. +## WhyLabs credentials -You can manage the API keys and container secrets in one of two ways, depending on your preferred setup: +- [WhyLabs API Key](#whylabs-api-key) +- [WhyLabs Container Password](#whylabs-container-password) -1. **Kubernetes Secret-based Management (default)** +### WhyLabs API Key - In this setup, secrets are passed as environment variables by creating Kubernetes Secrets manually. The following commands show how to create secrets for the API key and container authentication: +1. Create a [WhyLabs API Key](https://docs.whylabs.ai/docs/whylabs-api/#creating-an-api-token) - Use the following `kubectl` commands to create the required Kubernetes - `Secrets`. These secrets must exist prior to installing the Helm chart. +2. Store the API key in one of the following locations: - ```shell - # API that was created above - whylabs_api_key="" - # Arbitrary value that will be required to make requests to the containers - container_password="" - # Change this to the desired namespace - target_namespace="default" - # Helm release name (See installation for release_name usage) - release_name="" + - [Kubernetes Secret](#kubernetes-secret-default) + - [Mounted Volume](#mounted-volume) - kubectl create secret generic "whylabs-guardrails-api-key" \ - --namespace "${target_namespace}" \ - --from-literal=WHYLABS_API_KEY="${whylabs_api_key}" +#### Kubernetes Secret (Default) - kubectl create secret generic "whylabs-guardrails-api-secret" \ - --namespace "${target_namespace}" \ - --from-literal=CONTAINER_PASSWORD="${container_password}" +```shell +# WhyLabs API key +whylabs_api_key="" - kubectl create secret docker-registry "whylabs-${release_name}-registry-credentials" \ - --namespace "${target_namespace}" \ - --docker-server="registry.gitlab.com" \ - --docker-username="" \ - --docker-password="" \ - --docker-email="" - ``` +# Change this to the desired namespace +target_namespace="default" -2. **File-based Secrets Management with CSI Drivers** +# The `WHYLABS_API_KEY` key is used as the env variable name within the `Pod` +kubectl create secret generic "whylabs-guardrails-api-key" \ + --namespace "${target_namespace}" \ + --from-literal=WHYLABS_API_KEY="${whylabs_api_key}" +``` - If you prefer to use file-based secrets with tools like the AWS Secrets Store CSI Driver, you can configure the Helm chart to load secrets from files mounted into the container. To use file-based secrets, set envFrom: {} in your values.yaml file to disable the environment variable-based configuration. +#### Mounted Volume - Example configuration for file-based secrets: +Alternatively, any file mounted to `/var/run/secrets/whylabs.ai/env` will be automatically picked up by the container and used as an environment variable. The environment variable name will be the filename, and the file contents will be the value, e.g.: - - Modify the envFrom section in your `values.yaml`: +```shell +$ tree /var/run/secrets/whylabs.ai/env - ```yaml - envFrom: {} - ``` - - Use your CSI driver to mount secrets as files into the container, which allows - the application to read the secrets directly from the filesystem. +/var/run/secrets/whylabs.ai/env +├── whylabs_api_key +├── container_password +└── any_other_env_vars -### Choose Your Secret Management Strategy +$ cat /var/run/secrets/whylabs.ai/env/whylabs_api_key -- Environment Variables: This is the default method and requires you to populate secrets as Kubernetes environment variables. Leave the envFrom section in values.yaml unchanged or configure it with your Kubernetes secret references: +MyS3cr3tWhyL@b5@piK3y +``` - ```yaml - envFrom: - - secretRef: - name: whylabs-guardrails-api-key - optional: true - - secretRef: - name: whylabs-guardrails-api-secret - optional: true - ``` +Declare and mount the volumes by overriding `extraVolumes` and `extraVolumeMounts` in the `values.yaml` file. The following example assumes the use of the [AWS Secrets Store CSI Driver](https://github.com/aws/secrets-store-csi-driver-provider-aws), but the concept is the same for any other method of mounting files into the container. -- File-based Secrets: If you are using a CSI driver, set envFrom: {} in your -values.yaml and ensure your secrets are available as mounted files. +```yaml +extraVolumeMounts: + - name: whylabs-secret-provider + mountPath: /var/run/secrets/whylabs.ai/env + readOnly: true + +extraVolumes: + - name: whylabs-secret-provider + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: "your-whylabs-secret-provider-name" +``` -## Installation & Upgrades +### WhyLabs Container Password -> :warning: To expose guardrails to callers outside of your K8s cluster you will -need an Ingress Controller such as -[NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/), a -Gateway Controller such as [Ambassador](https://www.getambassador.io/), a -Service Mesh such as [Istio](https://istio.io/), or a Load Balancer Controller -such as [AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller). -The installation and configuration of the aforementioned controllers are outside -the scope of this document. However, for a quickstart guide to expose Guardrails -to the public internet via AWS LBC, see the -[Exposing Guardrails Outside Kubernetes](#exposing-guardrails-outside-kubernetes) -section. +The container password is an arbitrary value that must be included with every guardrails container request (required by default). To disable the container password, set the `DISABLE_CONTAINER_PASSWORD` environment variable to `True`. + +To store the container password in a Kubernetes Secret, run the following command: + +```shell +# Arbitrary value that will be required to make requests to the containers +container_password="" + +# Change this to the desired namespace +target_namespace="default" + +# The `CONTAINER_PASSWORD` key is used as the env variable name within the `Pod` +kubectl create secret generic "whylabs-guardrails-api-secret" \ + --namespace "${target_namespace}" \ + --from-literal=CONTAINER_PASSWORD="${container_password}" +``` + +Alternatively, the container password can be provided as a [mounted volume](#mounted-volume) as described in the [WhyLabs API Key](#whylabs-api-key) section. + +## Installation & Upgrades ### How to Use WhyLabs Helm Repository @@ -131,6 +139,16 @@ helm upgrade --install \ ## Exposing Guardrails Outside Kubernetes +> :warning: To expose guardrails to callers outside of your K8s cluster you will +need an Ingress Controller such as +[NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/), a +Gateway Controller such as [Ambassador](https://www.getambassador.io/), a +Service Mesh such as [Istio](https://istio.io/), or a Load Balancer Controller +such as [AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller). +The installation and configuration of the aforementioned controllers are outside +the scope of this document. However, for a quickstart guide to expose Guardrails +to the public internet via AWS LBC, see the following section. + This section serves as a quickstart guide to install AWS LBC and configure the Helm chart to expose Guardrails outside of your Kubernetes cluster via an internal NLB. @@ -164,9 +182,7 @@ service: The Horizontal Pod Autoscaler automatically scales the number of pods in a replication controller, deployment, replica set or stateful set based on -observed CPU utilization (or, with custom metrics support, on some other -application-provided metrics). The Horizontal Pod Autoscaler uses the following -formula to calculate the desired number of pods: +observed CPU utilization (among other metrics that are not in scope for this document). The Horizontal Pod Autoscaler uses the following default formula to calculate the desired number of pods: ```text Desired Replicas = [ (Current Utilization / Target Utilization) * Current Replicas ] @@ -185,25 +201,88 @@ Desired Replicas = ⌈ (90% / 50%) * 3 ⌉ HPA uses the same formula for both increasing and decreasing the number of pods. Horizontal pod scaling is disabled by default. To enable it, set the -`hpa.enabled` key to `true`. The pods QoS class will impact HPA behavior as a -deployment that is allowed to burst CPU usage will cause more aggressive HPA -scaling than a deployment with a `Guaranteed` QoS that does not go above 100% -utilization. +`autoscaling.enabled` to `true`. + +### Scaling Behavior configuration + +When using Horizontal Pod Autoscalers (HPAs) with default configurations users may encounter the following issues: + +- Frequent and rapid scaling operations +- Resource contention caused by aggressive scaling +- Startup time delays and queue buildup +- General behavior that appears as though the HPA is not working + +The following Horizontal Pod Autoscaler configuration is intended to provide a +reasonable starting point. :warning: Each deployment will have unique +characteristics that will require tuning scaling behavior based on factors +such as node size and type; starting replica count; request load; traffic +patterns, etc. The following concepts, referencing the example configuration +below, provide a framework for understanding how the HPA behavior configuration +works and how to tune it for optimal scaling. + +- The `scaleUp` and `scaleDown` policies limit the number of pods added or removed in a single evaluation period. +- The `stabilizationWindowSeconds` parameter ensures scaling decisions are based on an averaged utilization over 300 seconds, smoothing out temporary spikes or dips in resource usage. +- The 180-second `periodSeconds` ensures scaling operations are spaced out, allowing the system to stabilize before further scale operations occur. + +```yaml +autoscaling: + # Enable or disable HPA (Horizontal Pod Autoscaler). + enabled: false + + # The lower limit for the number of replicas to scale down + minReplicas: 1 + + # The upper limit for the number of replicas to scale up + maxReplicas: 100 + + # The specifications to use for calculating the desired replica count + targetCPUUtilizationPercentage: 70 + + # The behavior configuration for scaling up/down. + behavior: + + # This configuration provides two policies: a policy that scales the number + # of replicas by a fixed amount (4 pods), and a policy that scales the + # number of replicas by a percentage (50%). Setting `selectPolicy` to `Min` + # will select the scaling policy that creates the fewest number of replicas. + # The `stabilizationWindowSeconds` parameter smooths out temporary + # fluctuations in CPU utilization by evaluating recommendations over a + # 300-second window. + scaleUp: + policies: + - type: Pods + value: 4 + periodSeconds: 180 + - type: Percent + value: 50 + periodSeconds: 180 + selectPolicy: Min + stabilizationWindowSeconds: 300 + + scaleDown: + policies: + - type: Pods + value: 4 + periodSeconds: 180 + - type: Percent + value: 30 + periodSeconds: 180 + selectPolicy: Max + stabilizationWindowSeconds: 300 +``` ## Values | Key | Type | Default | Description | |-----|------|---------|-------------| -| affinity | object | `{}` | Affinity settings for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). If an explicit label selector is not provided for pod affinity or pod anti-affinity one will be created from the pod selector labels. | -| autoscaling | object | `{"behavior":{"scaleDown":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":30}],"selectPolicy":"Max","stabilizationWindowSeconds":300},"scaleUp":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":50}],"selectPolicy":"Min","stabilizationWindowSeconds":180}},"enabled":false,"maxReplicas":100,"minReplicas":1,"targetCPUUtilizationPercentage":70}` | [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) configuration for the `guardrails` container. | -| autoscaling.behavior | object | `{"scaleDown":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":30}],"selectPolicy":"Max","stabilizationWindowSeconds":300},"scaleUp":{"policies":[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":50}],"selectPolicy":"Min","stabilizationWindowSeconds":180}}` | Configures the scaling behavior of the target in both Up and Downdirections | -| autoscaling.behavior.scaleDown.policies | list | `[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":30}]` | Policies a list of potential scaling polices which can be used during scaling. At least one policy must be specified. | -| autoscaling.behavior.scaleDown.selectPolicy | string | `"Max"` | selectPolicy can be `Min` or `Max` and refers to scaling policy to choose when there are multiple policies; `Max` will choose the policy perform the largest scaling adjustment, while `Min` will choose the policy that performs the smallest scaling adjustment. | -| autoscaling.behavior.scaleDown.stabilizationWindowSeconds | int | `300` | StabilizationWindowSeconds is how many seconds the HPA looks back to determine if a policy is being met. | -| autoscaling.behavior.scaleUp.policies | list | `[{"periodSeconds":180,"type":"Pods","value":"{{ .Values.replicaCount | int }}"},{"periodSeconds":180,"type":"Percent","value":50}]` | Policies a list of potential scaling polices which can be used during scaling. At least one policy must be specified. | -| autoscaling.behavior.scaleUp.selectPolicy | string | `"Min"` | selectPolicy can be `Min` or `Max` and refers to scaling policy to choose when there are multiple policies; `Max` will choose the policy perform the largest scaling adjustment, while `Min` will choose the policy that performs the smallest scaling adjustment. | -| autoscaling.behavior.scaleUp.stabilizationWindowSeconds | int | `180` | StabilizationWindowSeconds is how many seconds the HPA looks back to determine if a policy is being met. | +| affinity | object | `{}` | [Affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) settings for `Pod`. | +| autoscaling.behavior.scaleUp.policies | list | `[]` | A list of potential [scaling polices](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#scaling-policies) which can be used during scaling | +| autoscaling.behavior.scaleUp.selectPolicy | string | `"Min"` | Selects which scaling policy to use; selects the policy that performs the `Max` or `Min` scaling. Also applies to `scaleDown` behavior. | +| autoscaling.behavior.scaleUp.stabilizationWindowSeconds | int | `300` | How many seconds the HPA looks back to determine if a policy is being met; uses the highest recommendation within the stabilization window. Also applies to `scaleDown` behavior. | | autoscaling.enabled | bool | `false` | Enable or disable HPA (Horizontal Pod Autoscaler). | +| autoscaling.maxReplicas | int | `100` | The upper limit for the number of replicas to which the autoscaler can scale up | +| autoscaling.minReplicas | int | 1 | The lower limit for the number of replicas to which the autoscaler can scale down | +| autoscaling.targetCPUUtilizationPercentage | int | 80 | The specifications for which to use to calculate the desired replica count | | cache.annotations | object | `{}` | Annotations for the cache. | | cache.duration | string | `"1m"` | Duration for cache validity. | | cache.enable | bool | `true` | Enable or disable caching. | @@ -211,15 +290,17 @@ utilization. | cache.labels | object | `{}` | Labels for the cache. | | cache.replicaCount | int | `1` | Number of replicas for the cache. | | commonLabels | object | `{}` | Labels to add to all chart resources. | -| env | object | `{"TENANCY_MODE":"{{ .Values.tenancyMode | default \"SINGLE\" }}"}` | [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `guardrails` container. | +| env | object | `{}` | [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `guardrails` container. **Supports Helm templating syntax**, e.g. you can use `{{ .Release.Name }}` or other templating variables, functions, and conditions within the the value of each environment variable. | | envFrom | list | `[{"secretRef":{"name":"whylabs-guardrails-api-key","optional":true}},{"secretRef":{"name":"whylabs-guardrails-api-secret","optional":true}}]` | Create environment variables from Kubernetes secrets or config maps. | +| envFrom[0].secretRef.name | string | `"whylabs-guardrails-api-key"` | Name of the Kubernetes secret containing the API key. The secret must be in the same namespace as the release and should be created prior to installing the chart. | +| envFrom[1].secretRef.name | string | `"whylabs-guardrails-api-secret"` | Name of the Kubernetes secret containing the container password, the value used when executing requests against the guardrails container. The secret must be in the same namespace as the release and should be created prior to installing the chart. | | extraVolumeMounts | list | `[]` | Extra [volume mounts](https://kubernetes.io/docs/concepts/storage/volumes/) for the `guardrails` container. | | extraVolumes | list | `[]` | Extra [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) for the `Pod`. | | fullnameOverride | string | `""` | Override the full name of the chart. | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy for the `guardrails` container. | | image.repository | string | `"registry.gitlab.com/whylabs/langkit-container"` | Image repository for the `guardrails` container. | | image.tag | string | `"2.2.2"` | Image tag for the `guardrails` container, this will default to `.Chart.AppVersion` if not set. | -| imagePullSecrets[0] | list | `{"name":""}` | Image pull secrets for the `guardrails` container. Defaults to `whylabs-{{ .Release.Name }}-registry-credentials` if `name: ""`. To exclude The ImagePullSecret entirely, set `imagePullSecrets: []` and comment out the list items. | +| imagePullSecrets | list | `[]` | | | ingress | object | `{"annotations":{},"className":"","enabled":false,"hosts":[{"host":"chart-example.local","paths":[{"path":"/","pathType":"ImplementationSpecific"}]}],"tls":[]}` | [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) configuration for the `guardrails` container. | | livenessProbe | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":8000},"periodSeconds":10}` | [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Failed livenessProbes restarts containers | | nameOverride | string | `""` | Override the name of the chart. | diff --git a/charts/guardrails/README.md.gotmpl b/charts/guardrails/README.md.gotmpl index 61778f2..c99f236 100644 --- a/charts/guardrails/README.md.gotmpl +++ b/charts/guardrails/README.md.gotmpl @@ -11,93 +11,101 @@ {{ template "chart.sourcesSection" . }} +- [Prerequisites](#prerequisites) +- [Configuring WhyLabs credentials](#whylabs-credentials) +- [Helm Chart Installation & Upgrades](#installation-upgrades) +- [Exposing Guardrails Outside Kubernetes](#exposing-guardrails-outside-kubernetes) +- [Horizontal Pod Autoscaling (HPA)](#horizontal-pod-autoscaling-hpa) + ## Prerequisites -### API Key and Secrets Management +- [Create and configure WhyLabs credentials](#whylabs-credentials) -Create a [WhyLabs API Key](https://docs.whylabs.ai/docs/whylabs-api/#creating-an-api-token) -that will be used when creating the required Kubernetes secrets to authenticate -with the WhyLabs API. +## WhyLabs credentials -You can manage the API keys and container secrets in one of two ways, depending on your preferred setup: +- [WhyLabs API Key](#whylabs-api-key) +- [WhyLabs Container Password](#whylabs-container-password) -1. **Kubernetes Secret-based Management (default)** +### WhyLabs API Key - In this setup, secrets are passed as environment variables by creating Kubernetes Secrets manually. The following commands show how to create secrets for the API key and container authentication: +1. Create a [WhyLabs API Key](https://docs.whylabs.ai/docs/whylabs-api/#creating-an-api-token) - Use the following `kubectl` commands to create the required Kubernetes - `Secrets`. These secrets must exist prior to installing the Helm chart. +2. Store the API key in one of the following locations: - ```shell - # API that was created above - whylabs_api_key="" - # Arbitrary value that will be required to make requests to the containers - container_password="" - # Change this to the desired namespace - target_namespace="default" - # Helm release name (See installation for release_name usage) - release_name="" + - [Kubernetes Secret](#kubernetes-secret-default) + - [Mounted Volume](#mounted-volume) - kubectl create secret generic "whylabs-guardrails-api-key" \ - --namespace "${target_namespace}" \ - --from-literal=WHYLABS_API_KEY="${whylabs_api_key}" +#### Kubernetes Secret (Default) - kubectl create secret generic "whylabs-guardrails-api-secret" \ - --namespace "${target_namespace}" \ - --from-literal=CONTAINER_PASSWORD="${container_password}" +```shell +# WhyLabs API key +whylabs_api_key="" - kubectl create secret docker-registry "whylabs-${release_name}-registry-credentials" \ - --namespace "${target_namespace}" \ - --docker-server="registry.gitlab.com" \ - --docker-username="" \ - --docker-password="" \ - --docker-email="" - ``` +# Change this to the desired namespace +target_namespace="default" -2. **File-based Secrets Management with CSI Drivers** +# The `WHYLABS_API_KEY` key is used as the env variable name within the `Pod` +kubectl create secret generic "whylabs-guardrails-api-key" \ + --namespace "${target_namespace}" \ + --from-literal=WHYLABS_API_KEY="${whylabs_api_key}" +``` - If you prefer to use file-based secrets with tools like the AWS Secrets Store CSI Driver, you can configure the Helm chart to load secrets from files mounted into the container. To use file-based secrets, set envFrom: {} in your values.yaml file to disable the environment variable-based configuration. +#### Mounted Volume - Example configuration for file-based secrets: +Alternatively, any file mounted to `/var/run/secrets/whylabs.ai/env` will be automatically picked up by the container and used as an environment variable. The environment variable name will be the filename, and the file contents will be the value, e.g.: - - Modify the envFrom section in your `values.yaml`: +```shell +$ tree /var/run/secrets/whylabs.ai/env - ```yaml - envFrom: {} - ``` - - Use your CSI driver to mount secrets as files into the container, which allows - the application to read the secrets directly from the filesystem. +/var/run/secrets/whylabs.ai/env +├── whylabs_api_key +├── container_password +└── any_other_env_vars -### Choose Your Secret Management Strategy +$ cat /var/run/secrets/whylabs.ai/env/whylabs_api_key -- Environment Variables: This is the default method and requires you to populate secrets as Kubernetes environment variables. Leave the envFrom section in values.yaml unchanged or configure it with your Kubernetes secret references: +MyS3cr3tWhyL@b5@piK3y +``` - ```yaml - envFrom: - - secretRef: - name: whylabs-guardrails-api-key - optional: true - - secretRef: - name: whylabs-guardrails-api-secret - optional: true - ``` +Declare and mount the volumes by overriding `extraVolumes` and `extraVolumeMounts` in the `values.yaml` file. The following example assumes the use of the [AWS Secrets Store CSI Driver](https://github.com/aws/secrets-store-csi-driver-provider-aws), but the concept is the same for any other method of mounting files into the container. -- File-based Secrets: If you are using a CSI driver, set envFrom: {} in your -values.yaml and ensure your secrets are available as mounted files. +```yaml +extraVolumeMounts: + - name: whylabs-secret-provider + mountPath: /var/run/secrets/whylabs.ai/env + readOnly: true + +extraVolumes: + - name: whylabs-secret-provider + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: "your-whylabs-secret-provider-name" +``` -## Installation & Upgrades +### WhyLabs Container Password -> :warning: To expose guardrails to callers outside of your K8s cluster you will -need an Ingress Controller such as -[NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/), a -Gateway Controller such as [Ambassador](https://www.getambassador.io/), a -Service Mesh such as [Istio](https://istio.io/), or a Load Balancer Controller -such as [AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller). -The installation and configuration of the aforementioned controllers are outside -the scope of this document. However, for a quickstart guide to expose Guardrails -to the public internet via AWS LBC, see the -[Exposing Guardrails Outside Kubernetes](#exposing-guardrails-outside-kubernetes) -section. +The container password is an arbitrary value that must be included with every guardrails container request (required by default). To disable the container password, set the `DISABLE_CONTAINER_PASSWORD` environment variable to `True`. + +To store the container password in a Kubernetes Secret, run the following command: + +```shell +# Arbitrary value that will be required to make requests to the containers +container_password="" + +# Change this to the desired namespace +target_namespace="default" + +# The `CONTAINER_PASSWORD` key is used as the env variable name within the `Pod` +kubectl create secret generic "whylabs-guardrails-api-secret" \ + --namespace "${target_namespace}" \ + --from-literal=CONTAINER_PASSWORD="${container_password}" +``` + +Alternatively, the container password can be provided as a [mounted volume](#mounted-volume) as described in the [WhyLabs API Key](#whylabs-api-key) section. + +## Installation & Upgrades ### How to Use WhyLabs Helm Repository @@ -138,6 +146,16 @@ helm upgrade --install \ ## Exposing Guardrails Outside Kubernetes +> :warning: To expose guardrails to callers outside of your K8s cluster you will +need an Ingress Controller such as +[NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/), a +Gateway Controller such as [Ambassador](https://www.getambassador.io/), a +Service Mesh such as [Istio](https://istio.io/), or a Load Balancer Controller +such as [AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller). +The installation and configuration of the aforementioned controllers are outside +the scope of this document. However, for a quickstart guide to expose Guardrails +to the public internet via AWS LBC, see the following section. + This section serves as a quickstart guide to install AWS LBC and configure the Helm chart to expose Guardrails outside of your Kubernetes cluster via an internal NLB. @@ -171,9 +189,7 @@ service: The Horizontal Pod Autoscaler automatically scales the number of pods in a replication controller, deployment, replica set or stateful set based on -observed CPU utilization (or, with custom metrics support, on some other -application-provided metrics). The Horizontal Pod Autoscaler uses the following -formula to calculate the desired number of pods: +observed CPU utilization (among other metrics that are not in scope for this document). The Horizontal Pod Autoscaler uses the following default formula to calculate the desired number of pods: ```text Desired Replicas = [ (Current Utilization / Target Utilization) * Current Replicas ] @@ -192,10 +208,75 @@ Desired Replicas = ⌈ (90% / 50%) * 3 ⌉ HPA uses the same formula for both increasing and decreasing the number of pods. Horizontal pod scaling is disabled by default. To enable it, set the -`hpa.enabled` key to `true`. The pods QoS class will impact HPA behavior as a -deployment that is allowed to burst CPU usage will cause more aggressive HPA -scaling than a deployment with a `Guaranteed` QoS that does not go above 100% -utilization. +`autoscaling.enabled` to `true`. + +### Scaling Behavior configuration + +When using Horizontal Pod Autoscalers (HPAs) with default configurations users may encounter the following issues: + +- Frequent and rapid scaling operations +- Resource contention caused by aggressive scaling +- Startup time delays and queue buildup +- General behavior that appears as though the HPA is not working + +The following Horizontal Pod Autoscaler configuration is intended to provide a +reasonable starting point. :warning: Each deployment will have unique +characteristics that will require tuning scaling behavior based on factors +such as node size and type; starting replica count; request load; traffic +patterns, etc. The following concepts, referencing the example configuration +below, provide a framework for understanding how the HPA behavior configuration +works and how to tune it for optimal scaling. + +- The `scaleUp` and `scaleDown` policies limit the number of pods added or removed in a single evaluation period. +- The `stabilizationWindowSeconds` parameter ensures scaling decisions are based on an averaged utilization over 300 seconds, smoothing out temporary spikes or dips in resource usage. +- The 180-second `periodSeconds` ensures scaling operations are spaced out, allowing the system to stabilize before further scale operations occur. + +```yaml +autoscaling: + # Enable or disable HPA (Horizontal Pod Autoscaler). + enabled: false + + # The lower limit for the number of replicas to scale down + minReplicas: 1 + + # The upper limit for the number of replicas to scale up + maxReplicas: 100 + + # The specifications to use for calculating the desired replica count + targetCPUUtilizationPercentage: 70 + + # The behavior configuration for scaling up/down. + behavior: + + # This configuration provides two policies: a policy that scales the number + # of replicas by a fixed amount (4 pods), and a policy that scales the + # number of replicas by a percentage (50%). Setting `selectPolicy` to `Min` + # will select the scaling policy that creates the fewest number of replicas. + # The `stabilizationWindowSeconds` parameter smooths out temporary + # fluctuations in CPU utilization by evaluating recommendations over a + # 300-second window. + scaleUp: + policies: + - type: Pods + value: 4 + periodSeconds: 180 + - type: Percent + value: 50 + periodSeconds: 180 + selectPolicy: Min + stabilizationWindowSeconds: 300 + + scaleDown: + policies: + - type: Pods + value: 4 + periodSeconds: 180 + - type: Percent + value: 30 + periodSeconds: 180 + selectPolicy: Max + stabilizationWindowSeconds: 300 +``` {{ template "chart.requirementsSection" . }} diff --git a/charts/guardrails/values.yaml b/charts/guardrails/values.yaml index 76efe6d..506d7b6 100644 --- a/charts/guardrails/values.yaml +++ b/charts/guardrails/values.yaml @@ -1,3 +1,52 @@ +# -- [Affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) settings for `Pod`. +affinity: {} + +autoscaling: + # -- Enable or disable HPA (Horizontal Pod Autoscaler). + enabled: false + # -- The lower limit for the number of replicas to which the autoscaler can scale down + # @default -- 1 + minReplicas: 1 + # -- The upper limit for the number of replicas to which the autoscaler can scale up + maxReplicas: 100 + # -- The specifications for which to use to calculate the desired replica count + # @default -- 80 + targetCPUUtilizationPercentage: 70 + # targetMemoryUtilizationPercentage: 70 + behavior: + # Scaling policies for increasing the number of replicas, can be `scaleUp` or `scaleDown`. + scaleUp: + # -- A list of potential [scaling polices](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#scaling-policies) + # which can be used during scaling + policies: + # @ignored + # Specifies the scaling policy of either `Pods` or `Percent` + - type: Pods + # The amount of change permitted by the policy + value: 4 + # specifies the window of time for which the policy should hold true. + periodSeconds: 180 + # @ignored + - type: Percent + value: 50 + periodSeconds: 180 + # -- Selects which scaling policy to use; selects the policy that performs the `Max` or `Min` scaling. + # Also applies to `scaleDown` behavior. + selectPolicy: Min + # -- How many seconds the HPA looks back to determine if a policy is being met; uses the highest + # recommendation within the stabilization window. Also applies to `scaleDown` behavior. + stabilizationWindowSeconds: 300 + # scaleDown: + # policies: + # - type: Pods + # value: 4 + # periodSeconds: 180 + # - type: Percent + # value: 30 + # periodSeconds: 180 + # selectPolicy: Max + # stabilizationWindowSeconds: 300 + cache: # -- Enable or disable caching. enable: true @@ -12,113 +61,114 @@ cache: # -- Labels for the cache. labels: {} -# -- (string) tenancyMode for the guardrails service. -# Must be `SINGLE` or `MULTI`. -tenancyMode: MULTI - -# -- Number of replicas for the service. -replicaCount: 4 - -image: - # -- Image repository for the `guardrails` container. - repository: registry.gitlab.com/whylabs/langkit-container - # -- Image pull policy for the `guardrails` container. - pullPolicy: IfNotPresent - # -- (string) Image tag for the `guardrails` container, this will default to - # `.Chart.AppVersion` if not set. - tag: "2.2.2" - -imagePullSecrets: - # -- (list) Image pull secrets for the `guardrails` container. Defaults to - # `whylabs-{{ .Release.Name }}-registry-credentials` if `name: ""`. To exclude - # The ImagePullSecret entirely, set `imagePullSecrets: []` and comment out the - # list items. - - name: "" - -# -- (string) Override the name of the chart. -nameOverride: "" - -# -- (string) Override the full name of the chart. -fullnameOverride: "" - # -- Labels to add to all chart resources. commonLabels: {} -# -- [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `guardrails` container. +# -- [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) +# for the `guardrails` container. **Supports Helm templating syntax**, e.g. you can use `{{ .Release.Name }}` or other +# templating variables, functions, and conditions within the the value of each environment variable. env: - # Uncomment WHYLABS_API_CACHE_ENDPOINT if .Values.cache.enable is true + # Uncomment WHYLABS_API_CACHE_ENDPOINT if .Values.cache.enable is true # WHYLABS_API_CACHE_ENDPOINT: "{{ .Release.Name }}.{{ .Release.Namespace }}.svc.cluster.local" + # @ignored TENANCY_MODE: "{{ .Values.tenancyMode | default \"SINGLE\" }}" # -- Create environment variables from Kubernetes secrets or config maps. envFrom: - secretRef: + # -- Name of the Kubernetes secret containing the API key. The secret must be in the same namespace as the + # release and should be created prior to installing the chart. name: whylabs-guardrails-api-key optional: true - secretRef: + # -- Name of the Kubernetes secret containing the container password, the value used when executing requests + # against the guardrails container. The secret must be in the same namespace as the release and should be + # created prior to installing the chart. name: whylabs-guardrails-api-secret optional: true -serviceAccount: - # -- If `true`, create a new `ServiceAccount`. - create: true - # -- (string) If this is set and `serviceAccount.create` is `true` this will be used for the created `ServiceAccount` name, if set and `serviceAccount.create` is `false` then this will define an existing `ServiceAccount` to use. - name: "" - # -- Labels to add to the service account. - labels: {} - # -- Annotations to add to the service account. - annotations: {} - # -- Set this to `false` to [opt out of API credential automounting](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#opt-out-of-api-credential-automounting) for the `ServiceAccount`. - automount: true +# -- Extra [volume mounts](https://kubernetes.io/docs/concepts/storage/volumes/) for the `guardrails` container. +extraVolumeMounts: [] -service: - # -- Service annotations. - annotations: {} - # -- Service Type, i.e. ClusterIp, LoadBalancer, etc. - type: ClusterIP - # -- Service HTTP port. - port: 80 - # -- The port on which the application container is listening. - targetPort: 8000 - -# -- Annotations to add to the `Pod`. -podAnnotations: {} +# -- Extra [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) for the `Pod`. +extraVolumes: [] -# -- Labels to add to the `Pod`. -podLabels: {} +# -- (string) Override the full name of the chart. +fullnameOverride: "" -# -- [Pod security context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core), this supports full customisation. -podSecurityContext: - runAsNonRoot: true +image: + # -- Image pull policy for the `guardrails` container. + pullPolicy: IfNotPresent + # -- Image repository for the `guardrails` container. + repository: registry.gitlab.com/whylabs/langkit-container + # -- (string) Image tag for the `guardrails` container, this will default to `.Chart.AppVersion` if not set. + tag: "2.2.2" -# -- [Security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) for the `guardrails` container. -securityContext: - privileged: false - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 - capabilities: - drop: ["ALL"] +imagePullSecrets: [] + # -- Image pull secrets for the `guardrails` container. If `name` is set to `""`, then the default value of + # `whylabs-{{ .Release.Name }}-registry-credentials` is used. + # - name: "" -# -- [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) configuration for the `guardrails` container. +# -- [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) configuration for the +# `guardrails` container. ingress: enabled: false className: "" annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" + # kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" hosts: - host: chart-example.local paths: - path: / pathType: ImplementationSpecific tls: [] - # - secretName: chart-example-tls - # hosts: + # - secretName: chart-example-tls hosts: # - chart-example.local -# -- [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `guardrails` container. +# -- [Liveness +# probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) +# configuration for the `guardrails` container. Failed livenessProbes restarts containers +livenessProbe: + httpGet: + path: /health + port: 8000 + failureThreshold: 5 + periodSeconds: 10 + +# -- (string) Override the name of the chart. +nameOverride: "" + +# -- Node labels to match for `Pod` +# [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). +nodeSelector: {} + +# -- Annotations to add to the `Pod`. +podAnnotations: {} + +# -- Labels to add to the `Pod`. +podLabels: {} + +# -- [Pod security +# context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core), this +# supports full customisation. +podSecurityContext: + runAsNonRoot: true + +# -- [Readiness +# probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) +# configuration for the `guardrails` container. Failed readinessProbes remove the pod from the service. +readinessProbe: + httpGet: + path: /health + port: 8000 + failureThreshold: 2 + periodSeconds: 10 + +# -- Number of replicas for the service. +replicaCount: 4 + +# -- [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `guardrails` +# container. resources: requests: cpu: "4" @@ -129,7 +179,47 @@ resources: memory: 4Gi ephemeral-storage: 250Mi -# -- [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Liveness and readiness probes are suppressed until the startup probe succeeds. +# -- [Security +# context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) +# for the `guardrails` container. +securityContext: + privileged: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + capabilities: + drop: ["ALL"] + +service: + # -- Service annotations. + annotations: {} + # -- Service Type, i.e. ClusterIp, LoadBalancer, etc. + type: ClusterIP + # -- Service HTTP port. + port: 80 + # -- The port on which the application container is listening. + targetPort: 8000 + +serviceAccount: + # -- If `true`, create a new `ServiceAccount`. + create: true + # -- (string) If this is set and `serviceAccount.create` is `true` this will be used for the created `ServiceAccount` + # name, if set and `serviceAccount.create` is `false` then this will define an existing `ServiceAccount` to use. + name: "" + # -- Labels to add to the service account. + labels: {} + # -- Annotations to add to the service account. + annotations: {} + # -- Set this to `false` to [opt out of API credential + # automounting](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#opt-out-of-api-credential-automounting) + # for the `ServiceAccount`. + automount: true + +# -- [Readiness +# probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) +# configuration for the `guardrails` container. Liveness and readiness probes are suppressed until the startup probe +# succeeds. startupProbe: httpGet: path: /health @@ -138,82 +228,9 @@ startupProbe: initialDelaySeconds: 20 periodSeconds: 10 -# -- [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Failed livenessProbes restarts containers -livenessProbe: - httpGet: - path: /health - port: 8000 - failureThreshold: 5 - periodSeconds: 10 - -# -- [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Failed readinessProbes remove the pod from the service. -readinessProbe: - httpGet: - path: /health - port: 8000 - failureThreshold: 2 - periodSeconds: 10 - -# -- [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) configuration for the `guardrails` container. -autoscaling: - # -- Enable or disable HPA (Horizontal Pod Autoscaler). - enabled: false - minReplicas: 1 - maxReplicas: 100 - # -- Configures the scaling behavior of the target in both Up and Downdirections - behavior: - scaleUp: - # -- Policies a list of potential scaling polices which can be used during scaling. At least one policy must be specified. - policies: - - type: Pods - value: "{{ .Values.replicaCount | int }}" - periodSeconds: 180 - - type: Percent - value: 50 - periodSeconds: 180 - # -- selectPolicy can be `Min` or `Max` and refers to scaling policy - # to choose when there are multiple policies; `Max` will choose the - # policy perform the largest scaling adjustment, while `Min` will - # choose the policy that performs the smallest scaling adjustment. - selectPolicy: Min - # -- StabilizationWindowSeconds is how many seconds the HPA looks back - # to determine if a policy is being met. - stabilizationWindowSeconds: 180 - scaleDown: - # -- Policies a list of potential scaling polices which can be used during scaling. At least one policy must be specified. - policies: - - type: Pods - value: "{{ .Values.replicaCount | int }}" - # periodSeconds is the rate at which a policy can be applied; - # this policy may only be applied once per period. - periodSeconds: 180 - - type: Percent - value: 30 - # periodSeconds is the rate at which a policy can be applied; - # this policy may only be applied once per period. - periodSeconds: 180 - # -- selectPolicy can be `Min` or `Max` and refers to scaling policy - # to choose when there are multiple policies; `Max` will choose the - # policy perform the largest scaling adjustment, while `Min` will - # choose the policy that performs the smallest scaling adjustment. - selectPolicy: Max - # -- StabilizationWindowSeconds is how many seconds the HPA looks back - # to determine if a policy is being met. - stabilizationWindowSeconds: 300 - targetCPUUtilizationPercentage: 70 - # targetMemoryUtilizationPercentage: 70 - -# -- Extra [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) for the `Pod`. -extraVolumes: [] - -# -- Extra [volume mounts](https://kubernetes.io/docs/concepts/storage/volumes/) for the `guardrails` container. -extraVolumeMounts: [] - -# -- Node labels to match for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). -nodeSelector: {} +# -- (string) tenancyMode for the guardrails service. Must be `SINGLE` or `MULTI`. +tenancyMode: MULTI -# -- Node taints which will be tolerated for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). +# -- Node taints which will be tolerated for `Pod` +# [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). tolerations: [] - -# -- Affinity settings for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). If an explicit label selector is not provided for pod affinity or pod anti-affinity one will be created from the pod selector labels. -affinity: {} From 32baa84ae554632013ecd9d22c544773b6854a53 Mon Sep 17 00:00:00 2001 From: AnchorArray Date: Tue, 3 Dec 2024 11:00:14 -0700 Subject: [PATCH 11/11] doc updates --- charts/guardrails/README.md | 4 ++-- charts/guardrails/README.md.gotmpl | 2 +- charts/guardrails/values.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/guardrails/README.md b/charts/guardrails/README.md index ad0177f..e72bd3a 100644 --- a/charts/guardrails/README.md +++ b/charts/guardrails/README.md @@ -6,7 +6,7 @@ A Helm chart for WhyLabs Guardrails - [Prerequisites](#prerequisites) - [Configuring WhyLabs credentials](#whylabs-credentials) -- [Helm Chart Installation & Upgrades](#installation-upgrades) +- [Helm Chart Installation & Upgrades](#installation--upgrades) - [Exposing Guardrails Outside Kubernetes](#exposing-guardrails-outside-kubernetes) - [Horizontal Pod Autoscaling (HPA)](#horizontal-pod-autoscaling-hpa) @@ -307,7 +307,7 @@ autoscaling: | nodeSelector | object | `{}` | Node labels to match for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). | | podAnnotations | object | `{}` | Annotations to add to the `Pod`. | | podLabels | object | `{}` | Labels to add to the `Pod`. | -| podSecurityContext | object | `{"runAsNonRoot":true}` | [Pod security context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core), this supports full customisation. | +| podSecurityContext | object | `{"runAsNonRoot":true}` | [Pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod), this supports full customisation. | | readinessProbe | object | `{"failureThreshold":2,"httpGet":{"path":"/health","port":8000},"periodSeconds":10}` | [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `guardrails` container. Failed readinessProbes remove the pod from the service. | | replicaCount | int | `4` | Number of replicas for the service. | | resources | object | `{"limits":{"cpu":"4","ephemeral-storage":"250Mi","memory":"4Gi"},"requests":{"cpu":"4","ephemeral-storage":"250Mi","memory":"4Gi"}}` | [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `guardrails` container. | diff --git a/charts/guardrails/README.md.gotmpl b/charts/guardrails/README.md.gotmpl index c99f236..23de5a5 100644 --- a/charts/guardrails/README.md.gotmpl +++ b/charts/guardrails/README.md.gotmpl @@ -13,7 +13,7 @@ - [Prerequisites](#prerequisites) - [Configuring WhyLabs credentials](#whylabs-credentials) -- [Helm Chart Installation & Upgrades](#installation-upgrades) +- [Helm Chart Installation & Upgrades](#installation--upgrades) - [Exposing Guardrails Outside Kubernetes](#exposing-guardrails-outside-kubernetes) - [Horizontal Pod Autoscaling (HPA)](#horizontal-pod-autoscaling-hpa) diff --git a/charts/guardrails/values.yaml b/charts/guardrails/values.yaml index 506d7b6..8f4771a 100644 --- a/charts/guardrails/values.yaml +++ b/charts/guardrails/values.yaml @@ -149,7 +149,7 @@ podAnnotations: {} podLabels: {} # -- [Pod security -# context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core), this +# context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod), this # supports full customisation. podSecurityContext: runAsNonRoot: true