Showing posts with label Docker. Show all posts
Showing posts with label Docker. Show all posts

Monday, 3 August 2026

Prometheus Metrics



The 4 Core Prometheus Metric Types


Prometheus defines four primary metric types. Choosing the right type depends on how the value behaves over time.


                              ┌───────────────────────────┐
                              │ Prometheus Metric Types   │
                              └─────────────┬─────────────┘
                                            │
         ┌───────────────────┬──────────────┴───────────────┬────────────────────┐
         ▼                   ▼                              ▼                    ▼
  ┌──────────────┐    ┌──────────────┐              ┌──────────────┐     ┌──────────────┐
  │    Gauge     │    │   Counter    │              │  Histogram   │     │   Summary    │
  ├──────────────┤    ├──────────────┤              ├──────────────┤     ├──────────────┤
  │ Value goes   │    │ Value ONLY   │              │ Groups values│     │ Calculates   │
  │ UP and DOWN  │    │ increases    │              │ into buckets │     │ quantiles    │
  │ (Snapshot)   │    │ (Cumulative) │              │ (Client-side)│     │ (Client-side)│
  └──────────────┘    └──────────────┘              └──────────────┘     └──────────────┘

1. Gauge


  • Behavior: Can increase, decrease, or stay the same.
  • Use Case: Current state, temperatures, memory usage, concurrent connections, replica counts.
  • PromQL Functions: avg_over_time(), max_over_time(), direct evaluation.

In Prometheus (and OpenMetrics standards), a Gauge is a metric that represents a single numerical value that can arbitrarily go up and down.

It acts like a digital display or a vehicle's speedometer—it gives you a point-in-time snapshot of a current state.

Understanding the Gauge Type


Because a Gauge can fluctuate freely, it is used to measure snapshot values, current state levels, and instantaneous statuses.

  • Example Real-World Analogy: A car's speedometer (can go from 0 to 70 mph, back to 30 mph), ambient temperature, or fuel tank level.
  • Kubernetes/KSM Examples:
    • kube_cronjob_status_last_successful_time: Holds a Unix timestamp (moves forward or stays fixed).
    • kube_deployment_status_replicas_available: Number of ready pods (e.g., 3 → 5 → 2).
    • node_memory_MemAvailable_bytes: Available system memory in bytes.

Key Feature: Instantaneous Operations


Because gauges fluctuate, you do not run rate or increase functions like rate() or increase() on them in PromQL. Instead, you query their current value directly or perform operations like running averages (avg_over_time()), min/max checks, or scalar math (e.g., time() - gauge).



2. Counter


  • Behavior: A cumulative metric that only increases (or resets to 0 upon process restart). It never decreases naturally.
  • Use Case: Counting total occurrences of events (e.g., total HTTP requests served, total pipeline errors, network bytes transmitted).
  • PromQL Functions: rate(), irate(), increase().

Why use a Counter instead of a Gauge? A counter allows PromQL's rate() function to accurately calculate "per-second rates" while automatically handling process restarts (resets).

3. Histogram


  • Behavior: Samples observations (usually things like request durations or payload sizes) and counts them in configurable buckets. It also provides a sum of all observed values.
  • Exposed Data:
    • <basename>_bucket{le="<upper_bound>"}: Counter of observations with value <= upper bound.
    • <basename>_count: Total number of observations (Counter).
    • <basename>_sum: Sum of all observed values (Counter).
  • Use Case: Measuring latencies, response times, or request sizes where you want to calculate percentiles (e.g., p95, p99) on the server side using PromQL (histogram_quantile()).

4. Summary


  • Behavior: Similar to a histogram, but calculates configurable quantiles (e.g., 0.50, 0.90, 0.99) directly on the client application side over a sliding time window.
  • Exposed Data:
    • <basename>{quantile="0.95"}: The 95th percentile value.
    • <basename>_count: Total observations.
    • <basename>_sum: Sum of observations.
  • Use Case: When client-side percentile calculation is required and you don't need to aggregate quantiles across multiple instances in Prometheus.


Summary Comparison Matrix


Metric Type
  • Can Decrease?
  • Typical PromQL Functions
  • Best Used For

Gauge
  • Yes
  • Direct value, avg_over_time()
  • Current state, memory usage, counts of current objects

Counter
  • No (only on restart)
  • rate(), increase()
  • Total count of events over time, request volume

Histogram
  • No (bucket counts increase)
  • histogram_quantile(), rate()
  • Request latencies, payload sizes (aggregatable)

Summary
  • No (counts/sums increase)
  • Direct quantile query
  • Request latencies (pre-calculated on client)




Container Metrics


container_memory_rss



container_memory_rss is a Prometheus metric (exposed by cAdvisor) that measures a container's Resident Set Size—specifically, the amount of physical RAM allocated to non-reclaimable, non-file-backed memory.

Key Technical Breakdown


Under the hood in Linux cgroups, container_memory_rss tracks:
  • Anonymous Memory: Process heap allocations, execution stack, and memory allocated via malloc or mmap(MAP_ANONYMOUS).  
  • Swap Cache: Memory swapped out to disk that is being brought back into RAM.

What it EXCLUDES:

Unlike standard Linux host RSS metrics, container_memory_rss in cAdvisor excludes file-backed page caches (memory used to cache files read from disk). Because of this, it only measures memory that cannot be automatically freed by the Linux kernel under memory pressure.  


container_memory_rss vs. Other Container Metrics


To understand its role, it helps to see how it fits into cAdvisor's other core memory metrics:

Metric
  • Includes
  • Purpose / Key Characteristic

container_memory_rss
  • Heap + Stack (Anonymous memory)
  • Stable indicator of process memory footprint. Does not fluctuate with disk I/O.

container_memory_working_set_bytes
  • Heap + Stack + Active Page Cache
  • What Kubernetes actually monitors. Fluctuates with file reads/writes.

container_memory_usage_bytes
  • Heap + Stack + Active Cache + Inactive Cache
  • Raw total RAM usage. Can be misleading because inactive cache is easily reclaimed by the OS.

Why is container_memory_rss Important?

  • Memory Leak Detection: Because it excludes cached file reads, container_memory_rss provides a much cleaner signal for application-level memory leaks. If this metric steadily climbs over time without dropping, your application (e.g., Go heap, JVM heap, Node process) is holding onto unmanaged memory. 
  • Debugging OOM Kills: While Kubernetes triggers OOMKills based on container_memory_working_set_bytes hitting resource limits, container_memory_rss helps you determine why it happened:  
    • High RSS + High Working Set --> Application memory leak or underestimated heap limit.
    • Low RSS + High Working Set --> Heavy disk I/O / file caching (e.g., reading massive log files or database indexes into memory).  

When container_memory_rss is NOT a relevant metric?


Example:

WiredTiger is the default storage engine that MongoDB (here, the Percona Server for MongoDB / PSMDB cluster) uses to actually read and write data to disk. In <ticketID> it matters specifically because of how it uses memory, which is what breaks those four Grafana alert rules.

The relevant behavior:

WiredTiger keeps a large in-memory cache. It maintains its own cache of frequently-accessed data and indexes, and it deliberately sizes that cache to roughly half the container's memory limit (the issue cites ~10 GiB against a 21Gi limit on rs0/rs2, and it's tunable per <ticketID>). WiredTiger runs its own eviction, targeting about 80% cache fill under normal operation and triggering aggressive eviction around 95%.

That cached data shows up as page cache, not RSS. This is the crux of the ticket. container_memory_rss counts anonymous/resident process memory but excludes the OS page cache — and for a WiredTiger workload the file-backed pages (the cache) are the bulk of the real footprint. So rss / limit sits structurally pinned around 50-58% no matter how much memory pressure the pod is actually under. An alert keyed on container_memory_rss > 0.90 can therefore never fire for a WiredTiger container. It's dead. (alert is defined as: container_memory_rss{container="mongod"} / limit > 0.90)

But you can't just switch to working-set either. container_memory_working_set_bytes does include those active file pages, so on the busy replicas it reads 95-96%. That looks alarming but is expected and healthy: it's the WiredTiger cache sitting at its designed ~half-of-limit size and WT's own eviction watermark. The kernel reclaims those pages under real pressure, and the evidence is that nothing in the mongodb namespace has ever been OOMKilled. Flipping the metric would just move the rule from never-firing to always-firing.

The signal that actually matters is WiredTiger cache fill. Because WT stalls user operations when its cache can't evict fast enough, the meaningful early-warning metric is cache utilization (the existing MongoDB WiredTiger cache fill — above 95% for 30m rule from <ticketID>), not container RSS or working set. That's why the ticket argues the RSS rules are redundant, not just broken, and leans toward deleting them.

So in this issue's context, "WiredTiger" is essentially shorthand for "a workload whose memory lives mostly in a large, self-managed, page-cache-backed database cache" — which is exactly the profile that makes RSS-based memory alerting meaningless and makes cache-fill the correct signal instead. (The same logic applies to the Elasticsearch rules, where the JVM heap plays the analogous role.)


Example PromQL Query


To track application heap growth without the noise of filesystem caching, query RSS like this:

# Rate of container RSS growth over 5-minute intervals
rate(container_memory_rss{namespace="production", container!=""}[5m])


container_memory_working_set_bytes


...

container_memory_usage_bytes


...

Monday, 24 November 2025

How to run Node, npm, Prettier, Yarn and Serverless via Docker

 

We sometimes don't want to pollute our local machine by installing Node if we don't use it often. In this scenario we can run a desired version of Node via Docker container:

docker run --rm \
  node:16-alpine \
  sh -c "node --version"

Output:

v16.20.2


Running npm

The above also means that we can use Node tools against our local Node application repository, without the need to install Node locally:

docker run --rm \
  -v "$PWD":/app \
  -w /app \
  node:16-alpine \
  sh -c "npm install && npm audit"


We can run npm audit fix to fix critical issues and npm audit fix --force to address all issues (including breaking changes).


The above command should be run from the project's root directory.

If package.json lists some dependencies from a private package hosted on GitHub Packages e.g.:

  "dependencies": {
    ...
    "@foo/bar": "^0.5.4",
    ...
  } 

...and inside Docker there is no GitHub token, npm install might throw this error if npm can't be authenticated against GitHub:

npm ERR! 401 Unauthorized - GET https://npm.pkg.github.com/download/@foo/bar/0.5.4/db46279e9b10a74cec83b15ac06422c479e4d193fd3c8366c839ace085244c9b - authentication token not provided

This token is GitHub Personal Access Token (PAT) and it should have a permission to read our private npm package.

If our local machine is authenticating via GitHub CLI (gh) we can run:

gh auth token

Output is PAT that npm can use and it will be in this format:

ghp_xxx...

We can store this value in the local env variable:

export NODE_AUTH_TOKEN=$(gh auth token)

We now need to create a local .npmrc file which contains authentication 

echo "@foo:registry=https://npm.pkg.github.com/" > .npmrc
echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> .npmrc

...so .npmrc file will look like this:

@foo:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=ghp_aAT3B3N...iiOO

If we try to execute npm install again, the issue with missing token should be resolved now.


Running Prettier

If prettier is added as devDependency in NodeJS project and .prettierrc config file is provided we can run prettier from Node Docker container, with no need to install Node on the local machine:

To find style errors:

docker run --rm \     
  -v "$PWD":/app \
  -w /app \
  node:18-alpine \
  sh -c "npm install && npx prettier --ignore-path .gitignore --check '**/*.+(ts|js|json|yml)'"

To fix the reported style errors:

docker run --rm \     
  -v "$PWD":/app \
  -w /app \
  node:18-alpine \
  sh -c "npm install && npx prettier --ignore-path .gitignore --write '**/*.+(ts|js|json|yml)'"


Running yarn

Node Docker image comes with yarn installed so we can use it just as we used npm:

docker run --rm \
  -v "$PWD":/app \
  -w /app \
  node:18-alpine \
  sh -c "yarn install --frozen-lockfile && yarn audit --audit-level=critical"


To remove some dependency:

docker run --rm \
  -v "$PWD":/app \
  -w /app \
  node:20-alpine \
  sh -c "yarn remove serverless-esbuild" 

Running Serverless


If we have Node-based Serverless project, we can run Serverless deployment from Node Docker container: 

docker run --rm \
  -v "$PWD":/app \
  -w /app \
  -e SERVERLESS_ACCESS_KEY=xxxx \
  node:18-alpine \
  sh -c "npm install -g serverless && yarn install --frozen-lockfile && yarn sls deploy --stage development"


Or like here:

docker run --rm \                              
  -v "$PWD":/app \
  -w /app -e SERVERLESS_ACCESS_KEY=xxxx \
  node:22-alpine \
  sh -c "npm install -g serverless && npm ci && sls deploy --stage development" 


Running tsc


docker run --rm \
  -v "$PWD":/app \
  -w /app -e SERVERLESS_ACCESS_KEY=xxx \
  node:22-alpine \
  sh -c "npm install -g serverless && npm ci && npx tsc -p ./tsconfig.json --noEmit --skipLibCheck"

---

How to run TypeScript compiler (tsc) via Docker

 

TypeScript compiler, often referred to as tsc , is responsible for compiling TypeScript code into JavaScript. It takes TypeScript source files as input and generates equivalent JavaScript files that can run in any JavaScript environment, ensuring compatibility with browsers.

If for any reason we don't want to install TypeScript compiler on our machine but want to use it to check the TypeScript syntax in the project, we can run in from a Docker container.

Let's first formulate a command which only checks the syntax:

tsc \
   --project ./tsconfig.json \
   --noEmit \
   --skipLibCheck

--project ./tsconfig.json - specifies the project configuration file (we can also use the short version of --project which is -p). tsc will compile only files included by that config.

--noEmit - TypeScript performs type-checking only, but does not output any .js, .d.ts, or build artifacts. Useful for: CI validation, pre-commit checks, linting purely for types, speeding up checks when we don’t care about compiled output.

--skipLibCheck - Tells TS not to check types inside node_modules or .d.ts libraries. This makes type checking much faster and avoids irrelevant type errors from dependencies. It skips: DefinitelyTyped typings, node_modules/*/*.d.ts, any imported library declaration file.


Before running TypeScript compiler, we need to install project's dependencies by running:

npm install

This is because:
  • This installs tsc (if package.json lists typescript among devDependencies, which it should in our case)
  • tsc must load types from our dependencies (@types/..., or any .d.ts shipped by packages).
  • Without node_modules, TypeScript cannot resolve imports like:
                import express from "express";

          and type-checking will fail.


If we have Node installed locally, we can run npm install before running Docker but otherwise, we can just invoke npm from the Docker image (npm install will install tsc):

docker run --rm \
  -v "$PWD":/app \
  -w /app \
  node:20-alpine \
  sh -c "npm install && npx tsc -p ./tsconfig.json --noEmit --skipLibCheck --listFiles --diagnostics"

-v "$PWD":/app - mounts our current directory to the container
-w /app - sets the working directory
node:20-alpine - lightweight Node image
npm install && npx tsc ... - installs project dependencies and runs TypeScript from our local node_modules


I also added --listFiles and --diagnostics flags, so tsc outputs something even if checks of all files pass as otherwise it will not emit any message.


If we are using Yarn instead of npm, we can call tsc directly from yarn:

docker run --rm \
  -v "$PWD":/app \
  -w /app \
  node:20-alpine \
  sh -c "yarn && yarn tsc -p ./tsconfig.json --noEmit --skipLibCheck"


---

Wednesday, 8 January 2025

How to locally run Helm from a Docker container


Instead of managing a local installation of Helm, I prefer using its latest version via Docker container: alpine/helm - Docker Image | Docker Hub.

% docker run -it --rm  -v ~/.helm:/root/.helm -v ~/.config/helm:/root/.config/helm -v ~/.cache/helm:/root/.cache/helm alpine/helm
The Kubernetes package manager

Common actions for Helm:

- helm search:    search for charts
- helm pull:      download a chart to your local directory to view
- helm install:   upload the chart to Kubernetes
- helm list:      list releases of charts

Environment variables:

| Name                               | Description                                                                                                |
|------------------------------------|------------------------------------------------------------------------------------------------------------|
| $HELM_CACHE_HOME                   | set an alternative location for storing cached files.                                                      |
| $HELM_CONFIG_HOME                  | set an alternative location for storing Helm configuration.                                                |
| $HELM_DATA_HOME                    | set an alternative location for storing Helm data.                                                         |
| $HELM_DEBUG                        | indicate whether or not Helm is running in Debug mode                                                      |
| $HELM_DRIVER                       | set the backend storage driver. Values are: configmap, secret, memory, sql.                                |
| $HELM_DRIVER_SQL_CONNECTION_STRING | set the connection string the SQL storage driver should use.                                               |
| $HELM_MAX_HISTORY                  | set the maximum number of helm release history.                                                            |
| $HELM_NAMESPACE                    | set the namespace used for the helm operations.                                                            |
| $HELM_NO_PLUGINS                   | disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.                                                 |
| $HELM_PLUGINS                      | set the path to the plugins directory                                                                      |
| $HELM_REGISTRY_CONFIG              | set the path to the registry config file.                                                                  |
| $HELM_REPOSITORY_CACHE             | set the path to the repository cache directory                                                             |
| $HELM_REPOSITORY_CONFIG            | set the path to the repositories file.                                                                     |
| $KUBECONFIG                        | set an alternative Kubernetes configuration file (default "~/.kube/config")                                |
| $HELM_KUBEAPISERVER                | set the Kubernetes API Server Endpoint for authentication                                                  |
| $HELM_KUBECAFILE                   | set the Kubernetes certificate authority file.                                                             |
| $HELM_KUBEASGROUPS                 | set the Groups to use for impersonation using a comma-separated list.                                      |
| $HELM_KUBEASUSER                   | set the Username to impersonate for the operation.                                                         |
| $HELM_KUBECONTEXT                  | set the name of the kubeconfig context.                                                                    |
| $HELM_KUBETOKEN                    | set the Bearer KubeToken used for authentication.                                                          |
| $HELM_KUBEINSECURE_SKIP_TLS_VERIFY | indicate if the Kubernetes API server's certificate validation should be skipped (insecure)                |
| $HELM_KUBETLS_SERVER_NAME          | set the server name used to validate the Kubernetes API server certificate                                 |
| $HELM_BURST_LIMIT                  | set the default burst limit in the case the server contains many CRDs (default 100, -1 to disable)         |
| $HELM_QPS                          | set the Queries Per Second in cases where a high number of calls exceed the option for higher burst values |

Helm stores cache, configuration, and data based on the following configuration order:

- If a HELM_*_HOME environment variable is set, it will be used
- Otherwise, on systems supporting the XDG base directory specification, the XDG variables will be used
- When no other location is set a default location will be used based on the operating system

By default, the default directories depend on the Operating System. The defaults are listed below:

| Operating System | Cache Path                | Configuration Path             | Data Path               |
|------------------|---------------------------|--------------------------------|-------------------------|
| Linux            | $HOME/.cache/helm         | $HOME/.config/helm             | $HOME/.local/share/helm |
| macOS            | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm      |
| Windows          | %TEMP%\helm               | %APPDATA%\helm                 | %APPDATA%\helm          |

Usage:
  helm [command]

Available Commands:
  completion  generate autocompletion scripts for the specified shell
  create      create a new chart with the given name
  dependency  manage a chart's dependencies
  env         helm client environment information
  get         download extended information of a named release
  help        Help about any command
  history     fetch release history
  install     install a chart
  lint        examine a chart for possible issues
  list        list releases
  package     package a chart directory into a chart archive
  plugin      install, list, or uninstall Helm plugins
  pull        download a chart from a repository and (optionally) unpack it in local directory
  push        push a chart to remote
  registry    login to or logout from a registry
  repo        add, list, remove, update, and index chart repositories
  rollback    roll back a release to a previous revision
  search      search for a keyword in charts
  show        show information of a chart
  status      display the status of the named release
  template    locally render templates
  test        run tests for a release
  uninstall   uninstall a release
  upgrade     upgrade a release
  verify      verify that a chart at the given path has been signed and is valid
  version     print the client version information

Flags:
      --burst-limit int                 client-side default throttling limit (default 100)
      --debug                           enable verbose output
  -h, --help                            help for helm
      --kube-apiserver string           the address and the port for the Kubernetes API server
      --kube-as-group stringArray       group to impersonate for the operation, this flag can be repeated to specify multiple groups.
      --kube-as-user string             username to impersonate for the operation
      --kube-ca-file string             the certificate authority file for the Kubernetes API server connection
      --kube-context string             name of the kubeconfig context to use
      --kube-insecure-skip-tls-verify   if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure
      --kube-tls-server-name string     server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used
      --kube-token string               bearer token used for authentication
      --kubeconfig string               path to the kubeconfig file
  -n, --namespace string                namespace scope for this request
      --qps float32                     queries per second used when communicating with the Kubernetes API, not including bursting
      --registry-config string          path to the registry config file (default "/root/.config/helm/registry/config.json")
      --repository-cache string         path to the directory containing cached repository indexes (default "/root/.cache/helm/repository")
      --repository-config string        path to the file containing repository names and URLs (default "/root/.config/helm/repositories.yaml")

Use "helm [command] --help" for more information about a command.


Example: Adding a Helm chart repository

% docker run -it --rm  -v ~/.helm:/root/.helm -v ~/.config/helm:/root/.config/helm -v ~/.cache/helm:/root/.cache/helm alpine/helm repo add elastic https://helm.elastic.co
"elastic" has been added to your repositories


Example: Updating a Helm chart repository

% docker run -it --rm  -v ~/.helm:/root/.helm -v ~/.config/helm:/root/.config/helm -v ~/.cache/helm:/root/.cache/helm alpine/helm repo update                             
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "elastic" chart repository
Update Complete. ⎈Happy Helming!⎈



Example: View all configurable values in a chart

% docker run -it --rm  -v ~/.helm:/root/.helm -v ~/.config/helm:/root/.config/helm -v ~/.cache/helm:/root/.cache/helm alpine/helm show values elastic/eck-operator
# nameOverride is the short name for the deployment. Leave empty to let Helm generate a name using chart values.
nameOverride: "elastic-operator"

# fullnameOverride is the full name for the deployment. Leave empty to let Helm generate a name using chart values.
fullnameOverride: "elastic-operator"

# managedNamespaces is the set of namespaces that the operator manages. Leave empty to manage all namespaces.
managedNamespaces: []

# installCRDs determines whether Custom Resource Definitions (CRD) are installed by the chart.
# Note that CRDs are global resources and require cluster admin privileges to install.
# If you are sharing a cluster with other users who may want to install ECK on their own namespaces, setting this to true can have unintended consequences.
# 1. Upgrades will overwrite the global CRDs and could disrupt the other users of ECK who may be running a different version.
# 2. Uninstalling the chart will delete the CRDs and potentially cause Elastic resources deployed by other users to be removed as well.
installCRDs: true

# replicaCount is the number of operator pods to run.
replicaCount: 1

image:
  # repository is the container image prefixed by the registry name.
  repository: docker.elastic.co/eck/eck-operator
  # pullPolicy is the container image pull policy.
  pullPolicy: IfNotPresent
  # tag is the container image tag. If not defined, defaults to chart appVersion.
  tag: null
  # fips specifies whether the operator will use a FIPS compliant container image for its own StatefulSet image.
  # This setting does not apply to Elastic Stack applications images.
  # Can be combined with config.ubiOnly.
  fips: false

# priorityClassName defines the PriorityClass to be used by the operator pods.
priorityClassName: ""

# imagePullSecrets defines the secrets to use when pulling the operator container image.
imagePullSecrets: []

# resources define the container resource limits for the operator.
resources:
  limits:
    cpu: 1
    memory: 1Gi
  requests:
    cpu: 100m
    memory: 150Mi

# statefulsetAnnotations define the annotations that should be added to the operator StatefulSet.
statefulsetAnnotations: {}

# statefulsetLabels define additional labels that should be added to the operator StatefulSet.
statefulsetLabels: {}

# podAnnotations define the annotations that should be added to the operator pod.
podAnnotations: {}

## podLabels define additional labels that should be added to the operator pod.
podLabels: {}

# podSecurityContext defines the pod security context for the operator pod.
podSecurityContext:
  runAsNonRoot: true

# securityContext defines the security context of the operator container.
securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop:
      - ALL
  readOnlyRootFilesystem: true
  runAsNonRoot: true

# nodeSelector defines the node selector for the operator pod.
nodeSelector: {}

# tolerations defines the node tolerations for the operator pod.
tolerations: []

# affinity defines the node affinity rules for the operator pod.
affinity: {}

# podDisruptionBudget configures the minimum or the maxium available pods for voluntary disruptions,
# set to either an integer (e.g. 1) or a percentage value (e.g. 25%).
podDisruptionBudget:
  enabled: false
  minAvailable: 1
  # maxUnavailable: 3

# additional environment variables for the operator container.
env: []

# additional volume mounts for the operator container.
volumeMounts: []

# additional volumes to add to the operator pod.
volumes: []

# createClusterScopedResources determines whether cluster-scoped resources (ClusterRoles, ClusterRoleBindings) should be created.
createClusterScopedResources: true

# Automount API credentials for the Service Account into the pod.
automountServiceAccountToken: true

serviceAccount:
  # create specifies whether a service account should be created for the operator.
  create: true
  # Specifies whether a service account should automount API credentials.
  automountServiceAccountToken: true
  # annotations to add to the service account
  annotations: {}
  # name of the service account to use. If not set and create is true, a name is generated using the fullname template.
  name: ""

tracing:
  # enabled specifies whether APM tracing is enabled for the operator.
  enabled: false
  # config is a map of APM Server configuration variables that should be set in the environment.
  config:
    ELASTIC_APM_SERVER_URL: http://localhost:8200
    ELASTIC_APM_SERVER_TIMEOUT: 30s

refs:
  # enforceRBAC specifies whether RBAC should be enforced for cross-namespace associations between resources.
  enforceRBAC: false

webhook:
  # enabled determines whether the webhook is installed.
  enabled: true
  # caBundle is the PEM-encoded CA trust bundle for the webhook certificate. Only required if manageCerts is false and certManagerCert is null.
  caBundle: Cg==
  # certManagerCert is the name of the cert-manager certificate to use with the webhook.
  certManagerCert: null
  # certsDir is the directory to mount the certificates.
  certsDir: "/tmp/k8s-webhook-server/serving-certs"
  # failurePolicy of the webhook.
  failurePolicy: Ignore
  # manageCerts determines whether the operator manages the webhook certificates automatically.
  manageCerts: true
  # namespaceSelector corresponds to the namespaceSelector property of the webhook.
  # Setting this restricts the webhook to act only on objects submitted to namespaces that match the selector.
  namespaceSelector: {}
  # objectSelector corresponds to the objectSelector property of the webhook.
  # Setting this restricts the webhook to act only on objects that match the selector.
  objectSelector: {}
  # port is the port that the validating webhook binds to.
  port: 9443
  # secret specifies the Kubernetes secret to be mounted into the path designated by the certsDir value to be used for webhook certificates.
  certsSecret: ""

# hostNetwork allows a Pod to use the Node network namespace.
# This is required to allow for communication with the kube API when using some alternate CNIs in conjunction with webhook enabled.
# CAUTION: Proceed at your own risk. This setting has security concerns such as allowing malicious users to access workloads running on the host.
hostNetwork: false

softMultiTenancy:
  # enabled determines whether the operator is installed with soft multi-tenancy extensions.
  # This requires network policies to be enabled on the Kubernetes cluster.
  enabled: false

# kubeAPIServerIP is required when softMultiTenancy is enabled.
kubeAPIServerIP: null

telemetry:
  # disabled determines whether the operator periodically updates ECK telemetry data for Kibana to consume.
  disabled: false
  # distributionChannel denotes which distribution channel was used to install the operator.
  distributionChannel: "helm"

# config values for the operator.
config:
  # logVerbosity defines the logging level. Valid values are as follows:
  # -2: Errors only
  # -1: Errors and warnings
  #  0: Errors, warnings, and information
  #  number greater than 0: Errors, warnings, information, and debug details.
  logVerbosity: "0"

  # (Deprecated: use metrics.port: will be removed in v2.14.0) metricsPort defines the port to expose operator metrics. Set to 0 to disable metrics reporting.
  metricsPort: 0

  metrics:
    # port defines the port to expose operator metrics. Set to 0 to disable metrics reporting.
    port: "0"
    # secureMode contains the options for enabling and configuring RBAC and TLS/HTTPs for the metrics endpoint.
    secureMode:
      # secureMode.enabled specifies whether to enable RBAC and TLS/HTTPs for the metrics endpoint.
      # * This option makes most sense when using a ServiceMonitor to scrape the metrics and is therefore mutually exclusive with the podMonitor.enabled option.
      # * This option also requires using cluster scoped resources (ClusterRole, ClusterRoleBinding) to
      #   grant access to the /metrics endpoint. (createClusterScopedResources: true is required)
      #
      enabled: false
      tls:
        # certificateSecret is the name of the tls secret containing the custom TLS certificate and key for the secure metrics endpoint.
        #
        # * This is an optional setting and is only required if you are using a custom TLS certificate. A self-signed certificate will be generated by default.
        # * TLS secret key must be named tls.crt.
        # * TLS key's secret key must be named tls.key.
        # * It is assumed to be in the same namespace as the ServiceMonitor.
        #
        # example: kubectl create secret tls eck-metrics-tls-certificate -n elastic-system \
        #            --cert=/path/to/tls.crt --key=/path/to/tls.key
        certificateSecret: ""

  # containerRegistry to use for pulling Elasticsearch and other application container images.
  containerRegistry: docker.elastic.co

  # containerRepository to use for pulling Elasticsearch and other application container images.
  # containerRepository: ""

  # containerSuffix suffix to be appended to container images by default. Cannot be combined with -ubiOnly flag
  # containerSuffix: ""

  # maxConcurrentReconciles is the number of concurrent reconciliation operations to perform per controller.
  maxConcurrentReconciles: "3"

  # caValidity defines the validity period of the CA certificates generated by the operator.
  caValidity: 8760h

  # caRotateBefore defines when to rotate a CA certificate that is due to expire.
  caRotateBefore: 24h

  # caDir defines the directory containing a CA certificate (tls.crt) and its associated private key (tls.key) to be used for all managed resources.
  # Setting this makes caRotateBefore and caValidity values ineffective.
  caDir: ""

  # certificatesValidity defines the validity period of certificates generated by the operator.
  certificatesValidity: 8760h

  # certificatesRotateBefore defines when to rotate a certificate that is due to expire.
  certificatesRotateBefore: 24h

  # disableConfigWatch specifies whether the operator watches the configuration file for changes.
  disableConfigWatch: false

  # exposedNodeLabels is an array of regular expressions of node labels which are allowed to be copied as annotations on Elasticsearch Pods.
  exposedNodeLabels: [ "topology.kubernetes.io/.*", "failure-domain.beta.kubernetes.io/.*" ]

  # ipFamily specifies the IP family to use. Possible values: IPv4, IPv6 and "" (auto-detect)
  ipFamily: ""

  # setDefaultSecurityContext determines whether a default security context is set on application containers created by the operator.
  # *note* that the default option now is "auto-detect" to attempt to set this properly automatically when both running
  # in an openshift cluster, and a standard kubernetes cluster.  Valid values are as follows:
  # "auto-detect" : auto detect
  # "true"        : set pod security context when creating resources.
  # "false"       : do not set pod security context when creating resources.
  setDefaultSecurityContext: "auto-detect"

  # kubeClientTimeout sets the request timeout for Kubernetes API calls made by the operator.
  kubeClientTimeout: 60s

  # elasticsearchClientTimeout sets the request timeout for Elasticsearch API calls made by the operator.
  elasticsearchClientTimeout: 180s

  # validateStorageClass specifies whether storage classes volume expansion support should be verified.
  # Can be disabled if cluster-wide storage class RBAC access is not available.
  validateStorageClass: true

  # enableLeaderElection specifies whether leader election should be enabled
  enableLeaderElection: true

  # Interval between observations of Elasticsearch health, non-positive values disable asynchronous observation.
  elasticsearchObservationInterval: 10s

  # ubiOnly specifies whether the operator will use only UBI container images to deploy Elastic Stack applications as well as for its own StatefulSet image. UBI images are only available from 7.10.0 onward.
  # Cannot be combined with the containerSuffix value.
  ubiOnly: false

# Prometheus PodMonitor configuration
# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#podmonitor
podMonitor:

  # enabled determines whether a podMonitor should deployed to scrape the eck metrics.
  # This requires the prometheus operator and the config.metrics.port not to be 0
  enabled: false

  # labels adds additional labels to the podMonitor
  labels: {}

  # annotations adds additional annotations to the podMonitor
  annotations: {}

  # namespace determines in which namespace the podMonitor will be deployed.
  # If not set the podMonitor will be created in the namespace where the Helm release is installed into
  # namespace: monitoring

  # interval specifies the interval at which metrics should be scraped
  interval: 5m

  # scrapeTimeout specifies the timeout after which the scrape is ended
  scrapeTimeout: 30s

  # podTargetLabels transfers labels on the Kubernetes Pod onto the target.
  podTargetLabels: []

  # podMetricsEndpointConfig allows to add an extended configuration to the podMonitor
  podMetricsEndpointConfig: {}
  # honorTimestamps: true

# Prometheus ServiceMonitor configuration
# Only used when config.enableSecureMetrics is true
# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#servicemonitor
serviceMonitor:
  # This option requires the following settings within Prometheus to function:
  # 1. RBAC settings for the Prometheus instance to access the metrics endpoint.
  #
  # - nonResourceURLs:
  #   - /metrics
  #   verbs:
  #   - get
  #
  # 2. If using the Prometheus Operator and your Prometheus instance is not in the same namespace as the operator you will need
  #    the Prometheus Operator configured with the following Helm values:
  #
  #   prometheus:
  #     prometheusSpec:
  #       serviceMonitorNamespaceSelector: {}
  #       serviceMonitorSelectorNilUsesHelmValues: false
  #
  # allows to disable the serviceMonitor, enabled by default for backwards compatibility
  enabled: true
  # namespace determines in which namespace the serviceMonitor will be deployed.
  # If not set the serviceMonitor will be created in the namespace where the Helm release is installed into
  # namespace: monitoring
  # caSecret is the name of the secret containing the custom CA certificate used to generate the custom TLS certificate for the secure metrics endpoint.
  #
  # * This *must* be the name of the secret containing the CA certificate used to sign the custom TLS certificate for the metrics endpoint.
  # * This secret *must* be in the same namespace as the Prometheus instance that will scrape the metrics.
  # * If using the Prometheus operator this secret must be within the `spec.secrets` field of the `Prometheus` custom resource such that it is mounted into the Prometheus pod at `caMountDirectory`, which defaults to /etc/prometheus/secrets/{secret-name}.
  # * This is an optional setting and is only required if you are using a custom TLS certificate.
  # * Key must be named ca.crt.
  #
  # example: kubectl create secret generic eck-metrics-tls-ca -n monitoring \
  #            --from-file=ca.crt=/path/to/ca.pem
  caSecret: ""
  # caMountDirectory is the directory at which the CA certificate is mounted within the Prometheus pod.
  #
  # * You should only need to adjust this if you are *not* using the Prometheus operator.
  caMountDirectory: "/etc/prometheus/secrets/"
  # insecureSkipVerify specifies whether to skip verification of the TLS certificate for the secure metrics endpoint.
  #
  # * If this setting is set to false, then the following settings are required:
  #   - certificateSecret
  #   - caSecret
  insecureSkipVerify: true

# Globals meant for internal use only
global:
  # manifestGen specifies whether the chart is running under manifest generator.
  # This is used for tasks specific to generating the all-in-one.yaml file.
  manifestGen: false
  # createOperatorNamespace defines whether the operator namespace manifest should be generated when in manifestGen mode.
  # Usually we do want that to happen (e.g. all-in-one.yaml) but, sometimes we don't (e.g. E2E tests).
  createOperatorNamespace: true
  # kubeVersion is the effective Kubernetes version we target when generating the all-in-one.yaml.
  kubeVersion: 1.21.0