Documentation / opensearch
OpenSearch
Installs OpenSearch, the search and analytics engine: a single node, or a cluster of nodes that each hold data and are eligible as cluster manager, with OpenSearch Dashboards as an option.
The chart provides:
- a cluster of three nodes by default, with every index able to keep a replica on another node;
- TLS on every connection, between the nodes and to the REST API, with a certificate authority of the cluster’s own, made with cert-manager;
- authentication on every request, with a generated administrator password and none of the image’s demonstration users;
- scheduled snapshots of every index to S3-compatible storage, and restore from them;
- OpenSearch Dashboards, the web interface, on an optional Ingress;
- a NetworkPolicy;
- every Pod meeting the
restrictedPod Security Standard, with nothing run as root or privileged.
Prerequisites
- Kubernetes 1.33 or later.
-
vm.max_map_countof at least 262144 on every node that may run OpenSearch. OpenSearch refuses to start without it, and a Pod cannot set it without privilege, which the chart never asks for. The Bahriya Kubernetes Engine will set it on every node from release 2.5. On earlier releases of the Bahriya Kubernetes Engine and on other Kubernetes, set it on every node and keep it across reboots:echo 'vm.max_map_count = 262144' > /etc/sysctl.d/90-opensearch.conf sysctl --system - cert-manager, for the cluster’s certificates. It is included with the Bahriya Kubernetes Engine; on other Kubernetes, install it first.
- A pull secret for
1x.axnamed1x-axin the release’s namespace, created from an image token as described in the access documentation. - A StorageClass for the volumes: the cluster’s default, or one named in
persistence.storageClass.
Installation
helm install logs tersane/opensearch \
--namespace logs --create-namespace \
--version <chart version>
A single node:
helm install logs tersane/opensearch --namespace logs --set replicas=1
The release’s resources are named <release>-opensearch (here
logs-opensearch), or after the release alone if its name already contains
opensearch. Check that every node is ready:
kubectl --namespace logs get pods -l app.kubernetes.io/instance=logs
Connecting
The REST API is served over HTTPS at https://<release>-opensearch:9200.
Clients verify the server with ca.crt from the Secret
<release>-opensearch-certs; the certificate names the Service in its short
and namespaced forms, and any names in extraDnsNames.
The administrator is admin; its password is in the Secret
<release>-opensearch, key admin-password:
kubectl --namespace logs get secret logs-opensearch \
-o jsonpath='{.data.admin-password}' | base64 -d
Users and roles
The chart creates two users: admin, with every permission, and
kibanaserver, which OpenSearch Dashboards connects as. The image’s
demonstration users are not created. Further users, roles and role mappings
are managed with the security REST API or in OpenSearch Dashboards, under
Security, and are kept in the cluster:
curl --cacert ca.crt -u admin:<password> -X PUT \
https://logs-opensearch:9200/_plugins/_security/api/internalusers/ingest \
-H 'Content-Type: application/json' \
-d '{"password":"<password>","backend_roles":["logstash"]}'
The two users’ passwords are set when the cluster is created. To use
passwords of your own, create the Secret before installing and name it in
auth.existingSecret, with the keys admin-password, admin-hash,
dashboards-password and dashboards-hash, where each hash is the bcrypt
hash of its password. A password changed later is changed with the security
REST API, and the Secret updated to match, since the chart’s Secret is what
Dashboards, the snapshot Job and helm test read.
High availability
With three nodes, the cluster keeps a majority of cluster managers while one
node is down, and an index with number_of_replicas: 1 (OpenSearch’s
default) keeps every shard. Nodes are spread across the cluster’s nodes by a
preferred anti-affinity on affinity.topologyKey, and a PodDisruptionBudget
lets a node drain take one OpenSearch node at a time. A change to the chart’s
configuration restarts the nodes one at a time.
Snapshots
snapshots:
enabled: true
bucket: my-bucket
basePath: opensearch/logs
endpoint: s3.example.com # empty for Amazon S3
existingSecret: logs-s3 # keys access-key and secret-key
schedule: "0 2 * * *"
timezone: UTC
maxAge: 30d
The key is kept in OpenSearch’s keystore on each node. After every install
and upgrade, a Job registers the repository (snapshots.repository,
s3-snapshots by default), checks that every node can write to it, and
creates or replaces a snapshot schedule named after the release: a snapshot
of every index and the cluster state on schedule, deleting those older than
maxAge and always keeping the most recent. A changed key takes effect when
the nodes restart.
To restore an index, delete or close it, and restore it from a snapshot:
curl --cacert ca.crt -u admin:<password> \
https://logs-opensearch:9200/_snapshot/s3-snapshots/_all
curl --cacert ca.crt -u admin:<password> -X POST \
'https://logs-opensearch:9200/_snapshot/s3-snapshots/<snapshot>/_restore?wait_for_completion=true' \
-H 'Content-Type: application/json' -d '{"indices":"orders"}'
OpenSearch Dashboards
dashboards:
enabled: true
ingress:
enabled: true
host: search.example.com
tlsSecret: search-example-com-tls
Dashboards connects to OpenSearch over HTTPS as kibanaserver, verifying the
cluster’s certificate. Sign in with OpenSearch’s own users. TLS to the browser
is terminated by the ingress controller; with a tlsSecret, Dashboards’ cookie
is sent over HTTPS only.
Network policy
With networkPolicy.enabled (the default), the nodes admit:
- the REST API on 9200 from
networkPolicy.http.from, every source when it is empty; - always, the nodes themselves on 9200 and 9300, and the chart’s own clients (Dashboards, the snapshot Job and the test) on 9200.
Dashboards admits port 5601 from networkPolicy.dashboards.from, every
source when it is empty.
Resources
The Java heap is half the memory limit, as OpenSearch recommends; the other
half is left to the operating system’s file cache, which OpenSearch relies on
for search. Give the memory limit in Mi or Gi. The init container runs
OpenSearch’s keystore tool, with its own small heap, under initResources.
Certificates
The cluster’s certificate authority is valid for ten years, and the nodes’
certificate for one; cert-manager renews it thirty days before it expires.
The nodes read the renewed certificate on their next restart, or at once
when asked to reload it. The reload must be asked with the administrator’s
certificate, from the Secret <release>-opensearch-admin-certs; the security
plugin refuses it to the admin user’s password:
kubectl --namespace logs get secret logs-opensearch-admin-certs \
-o jsonpath='{.data.tls\.crt}' | base64 -d > admin.crt
kubectl --namespace logs get secret logs-opensearch-admin-certs \
-o jsonpath='{.data.tls\.key}' | base64 -d > admin.key
for layer in transport http; do
curl --cacert ca.crt --cert admin.crt --key admin.key -X PUT \
"https://logs-opensearch:9200/_plugins/_security/api/ssl/$layer/reloadcerts"
done
The same certificate is what the security plugin’s securityadmin tool
presents. It is mounted in no Pod; keep the files you extract as you would the
administrator’s password.
Pod Security
Every Pod the chart creates meets the Kubernetes restricted Pod Security
Standard: it runs as the image’s opensearch user, cannot escalate its
privileges, drops all Linux capabilities and runs under the container
runtime’s default seccomp profile. Install it in a namespace that enforces
restricted.
Testing
helm test logs --namespace logs
The test checks, as the administrator over HTTPS, that the cluster has every node and is not red, indexes a document in a new index, finds it with a search and deletes the index.
Uninstalling
helm uninstall logs --namespace logs
The volumes are kept; delete them to remove the data:
kubectl --namespace logs delete pvc -l app.kubernetes.io/instance=logs
Parameters
OpenSearch
| Parameter | Description | Default |
|---|---|---|
replicas |
Nodes: 1 is a single node | 3 |
image.repository / image.tag |
OpenSearch with the S3 snapshot plugin | 1x.ax/tersane/core/opensearch/opensearch / the release’s |
imagePullSecrets |
Pull secrets of every Pod | [{name: 1x-ax}] |
config |
opensearch.yml settings added to the chart’s | {} |
auth.existingSecret |
A Secret with both users’ passwords and hashes | generated |
extraDnsNames |
Names the HTTPS certificate carries besides the Service’s | [] |
clusterDomain |
The cluster’s DNS domain | cluster.local |
Storage, resources and scheduling
| Parameter | Description | Default |
|---|---|---|
persistence.size / .storageClass |
Volume size per node; StorageClass | 20Gi / the default class |
resources |
Requests and limits of each node; the heap is half the memory limit | 500m/2Gi, limits 2000m/2Gi |
initResources |
Requests and limits of the init container | 100m/256Mi, limits 1000m/256Mi |
jobResources |
Requests and limits of the snapshot Job and the test | 10m/32Mi, limits 200m/128Mi |
terminationGracePeriodSeconds |
The longest a node takes to stop | 120 |
podDisruptionBudget.enabled / .maxUnavailable |
Nodes a drain may take at once | true / 1 |
affinity.topologyKey / .podAntiAffinityType |
Spread of the nodes | kubernetes.io/hostname / preferred |
nodeSelector, tolerations, priorityClassName |
Placement of the nodes | none |
Snapshots
| Parameter | Description | Default |
|---|---|---|
snapshots.enabled |
Scheduled snapshots to S3 | false |
snapshots.bucket / .basePath |
Where snapshots are kept | "" |
snapshots.endpoint / .protocol / .region / .pathStyleAccess |
The storage | "" / https / "" / true |
snapshots.accessKey / .secretKey / .existingSecret |
The key, or a Secret with access-key and secret-key |
"" |
snapshots.schedule / .timezone |
When a snapshot is taken | 0 2 * * * / UTC |
snapshots.maxAge |
How long snapshots are kept | 30d |
snapshots.repository |
The repository’s name | s3-snapshots |
Dashboards and network
| Parameter | Description | Default |
|---|---|---|
dashboards.enabled |
OpenSearch Dashboards | false |
dashboards.replicas / .resources |
Its replicas and resources | 1 / 100m/512Mi, limits 1000m/1Gi |
dashboards.image.repository / .tag |
Its image | 1x.ax/tersane/core/opensearch/opensearch-dashboards / the release’s |
dashboards.ingress.enabled / .host / .ingressClassName / .tlsSecret / .annotations |
Its Ingress | false / "" / kong / "" / {} |
networkPolicy.enabled |
Create the NetworkPolicies | true |
networkPolicy.http.from / .dashboards.from |
Sources admitted to 9200 and 5601 | [] (every source) |