Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

Read more

OpenSearch Kubernetes Operator Quickstart: Deploy and Manage OpenSearch Clusters on Kubernetes

Learn how to deploy, scale, and manage OpenSearch clusters on Kubernetes using the official OpenSearch Kubernetes Operator. This comprehensive guide covers installation, configuration, security, monitoring, and production best practices for running OpenSearch workloads in Kubernetes environments.

Watch the complete video series: Deploying OpenSearch on Kubernetes with the Operator

What is OpenSearch Kubernetes Operator?

The OpenSearch Kubernetes Operator is a powerful tool that automates the deployment, provisioning, management, and orchestration of OpenSearch clusters and OpenSearch Dashboards on Kubernetes. Built for cloud-native environments, it simplifies complex operations like scaling, version upgrades, security configuration, and cluster management.

API Group Migration Notice: The operator is migrating from opensearch.opster.io to opensearch.org API group. Both are currently supported, but opensearch.opster.io is deprecated. Please migrate your resources to use apiVersion: opensearch.org/v1.

Prerequisites

Before installing the OpenSearch Kubernetes Operator, ensure your environment meets these requirements:

Kubernetes Environment

  • Kubernetes Version: v1.19 or higher
  • Cluster Access: kubectl configured with admin privileges
  • Node Resources: Minimum 4 CPU cores and 8GB RAM available across cluster nodes
  • Storage: Dynamic persistent volume provisioner configured (recommended)

Network Requirements

  • Pod Network: Cluster networking properly configured
  • Service Access: LoadBalancer or NodePort support for external access
  • DNS: CoreDNS or equivalent for service discovery

Compatibility Matrix

The OpenSearch Kubernetes Operator supports multiple OpenSearch versions:

Operator Version Min OpenSearch Version Max OpenSearch Version Kubernetes Version
3.0.0 2.19.2 latest 3.x 1.19+
2.8.0 2.19.2 latest 3.x 1.19+
2.7.0, 2.6.x, 2.5.x 1.3.x 2.19.2 1.19+

This table only lists versions that have been explicitly tested with the operator. The operator will not prevent you from using other versions, but you should test in a non-production environment first.

Installation Guide

Step 1: Add the Helm Repository

helm repo add opensearch-operator https://opensearch-project.github.io/opensearch-k8s-operator/
helm repo update

Step 2: Install the Operator

helm install opensearch-operator opensearch-operator/opensearch-operator

Verify the operator is running:

kubectl get pods -l app.kubernetes.io/name=opensearch-operator

Deploy Your First OpenSearch Cluster

Step 3: Create a Basic OpenSearch Cluster

Create a file named my-opensearch-cluster.yaml:

apiVersion: opensearch.org/v1
kind: OpenSearchCluster
metadata:
  name: my-first-cluster
  namespace: default
spec:
  security:
    config:
    tls:
       http:
         generate: true
       transport:
         generate: true
         perNode: true
  general:
    httpPort: 9200
    serviceName: my-first-cluster
    version: 3
    pluginsList: ["repository-s3"]
    drainDataNodes: true
  dashboards:
    tls:
      enable: true
      generate: true
    version: 3
    enable: true
    replicas: 1
    resources:
      requests:
         memory: "512Mi"
         cpu: "200m"
      limits:
         memory: "512Mi"
         cpu: "200m"
  nodePools:
    - component: masters
      replicas: 3
      diskSize: "30Gi"
      resources:
         requests:
            memory: "4Gi"
            cpu: "1000m"
         limits:
            memory: "4Gi"
            cpu: "1000m"
      roles:
        - "data"
        - "cluster_manager"
      persistence:
         emptyDir: {}

Note: Single-node clusters are currently not supported. Your cluster must have at least 3 nodes with the cluster_manager role configured.

Step 4: Deploy the Cluster

kubectl apply -f my-opensearch-cluster.yaml

The operator will first create a bootstrap pod (my-first-cluster-bootstrap-0) that helps with initial master discovery. The bootstrap pod uses persistent storage (PVC) to maintain cluster state across restarts during initialization.

Step 5: Monitor Deployment

Check the status of your cluster:

kubectl get opensearchclusters
kubectl get pods -l opensearch.org/opensearch-cluster=my-first-cluster

Wait for all pods to be in Running state.

Access and Security

Authentication and Credentials

The OpenSearch Kubernetes Operator automatically configures security features including authentication, authorization, and TLS encryption.

Retrieve Admin Credentials

The operator generates secure admin credentials automatically. If you don't provide an adminCredentialsSecret, the operator creates <cluster-name>-admin-password with a random password:

# Get admin password
ADMIN_PASSWORD=$(kubectl get secret my-first-cluster-admin-password -o jsonpath='{.data.password}' | base64 -d)
echo "Admin password: $ADMIN_PASSWORD"

# Default admin username is 'admin'
ADMIN_USER="admin"

The operator automatically generates the password hash and configures it in the security config, so you don't need to manage password hashes manually.

Create Additional Users

You can create custom users by configuring security settings:

spec:
  security:
    config:
      securityConfigSecret:
        name: opensearch-security-config

Network Access Options

Option 1: Port Forwarding (Development)

For local development and testing:

# Access OpenSearch API
kubectl port-forward svc/my-first-cluster 9200:9200

# Access OpenSearch Dashboards
kubectl port-forward svc/my-first-cluster-dashboards 5601:5601

Option 2: LoadBalancer Service (Production)

For production environments, expose services via LoadBalancer:

spec:
  general:
    serviceType: LoadBalancer
  dashboards:
    service:
      type: LoadBalancer

Option 3: Ingress Controller

Configure ingress for domain-based access:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: opensearch-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  tls:
  - hosts:
    - opensearch.example.com
    secretName: opensearch-tls
  rules:
  - host: opensearch.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-first-cluster
            port:
              number: 9200

API Access and Testing

Basic Health Check

curl -k -u admin:$ADMIN_PASSWORD https://localhost:9200/_cluster/health?pretty

Advanced API Operations

# Check cluster nodes
curl -k -u admin:$ADMIN_PASSWORD https://localhost:9200/_cat/nodes?v

# List indices
curl -k -u admin:$ADMIN_PASSWORD https://localhost:9200/_cat/indices?v

# Create a test index
curl -k -u admin:$ADMIN_PASSWORD -X PUT https://localhost:9200/test-index \
  -H 'Content-Type: application/json' \
  -d '{"settings": {"number_of_shards": 1, "number_of_replicas": 1}}'

TLS Certificate Management

The operator automatically manages TLS certificates for secure communication with TLS hot reloading support:

spec:
  security:
    tls:
      http:
        generate: true        # Auto-generate HTTP certificates
        duration: "8760h"     # Certificate validity (default: 1 year)
        secret:
          name: ""           # Optional: Use existing certificate
      transport:
        generate: true        # Auto-generate transport certificates
        perNode: true        # Generate per-node certificates
        duration: "8760h"     # Certificate validity (default: 1 year)

You can configure certificate validity using the duration field (e.g., "720h", "17520h"). If omitted, it defaults to one year ("8760h"). The operator supports certificate rotation by reissuing certs when near expiry.

Advanced Configuration

Multi-Node Pool Architecture

Configure different node pools for optimal performance and resource utilization:

spec:
  nodePools:
    # Master-eligible nodes
    - component: masters
      replicas: 3
      roles: ["cluster_manager"]
      resources:
        requests:
          memory: "2Gi"
          cpu: "1000m"
        limits:
          memory: "2Gi"
          cpu: "1000m"
      persistence:
        pvc:
          storageClass: "fast-ssd"
          size: "20Gi"

    # Dedicated data nodes
    - component: data-nodes
      replicas: 4
      roles: ["data"]
      resources:
        requests:
          memory: "16Gi"
          cpu: "4000m"
        limits:
          memory: "16Gi"
          cpu: "4000m"
      persistence:
        pvc:
          storageClass: "high-iops"
          size: "500Gi"

    # Coordinating nodes for query handling
    - component: coordinators
      replicas: 2
      roles: ["coordinating_only"]
      resources:
        requests:
          memory: "4Gi"
          cpu: "2000m"
        limits:
          memory: "4Gi"
          cpu: "2000m"

Hot-Warm-Cold Architecture

Implement tiered storage for cost optimization:

spec:
  nodePools:
    # Hot nodes - latest data, high performance
    - component: hot-nodes
      replicas: 3
      roles: ["data", "data_hot"]
      resources:
        requests:
          memory: "32Gi"
          cpu: "8000m"
      persistence:
        pvc:
          storageClass: "nvme-ssd"
          size: "1Ti"
      jvm: "-Xms16g -Xmx16g"

    # Warm nodes - older frequently accessed data
    - component: warm-nodes
      replicas: 4
      roles: ["data", "data_warm"]
      resources:
        requests:
          memory: "16Gi"
          cpu: "4000m"
      persistence:
        pvc:
          storageClass: "premium-ssd"
          size: "2Ti"
      jvm: "-Xms8g -Xmx8g"

    # Cold nodes - archive data, cost-optimized
    - component: cold-nodes
      replicas: 2
      roles: ["data", "data_cold"]
      resources:
        requests:
          memory: "8Gi"
          cpu: "2000m"
      persistence:
        pvc:
          storageClass: "standard"
          size: "5Ti"
      jvm: "-Xms4g -Xmx4g"

Custom OpenSearch Configuration

Configure OpenSearch settings for your use case:

spec:
  general:
    version: "2.14.0"
    pluginsList:
      - "repository-s3"
      - "repository-azure"
      - "ingest-attachment"
      - "analysis-icu"
    additionalConfig:
      opensearch.yml: |
        cluster.routing.allocation.disk.watermark.low: 85%
        cluster.routing.allocation.disk.watermark.high: 90%
        cluster.routing.allocation.disk.watermark.flood_stage: 95%
        indices.recovery.max_bytes_per_sec: 100mb
        indices.memory.index_buffer_size: 20%
        thread_pool.search.queue_size: 10000
        thread_pool.write.queue_size: 10000

SmartScaler

SmartScaler is a mechanism built into the Operator that enables nodes to be safely removed from the cluster. When a node is being removed, the safe drain process ensures that all of its data is transferred to other nodes in the cluster before the node is taken offline. This prevents any data loss or corruption.

During the safe drain process:

  • The node being removed is marked as "draining" and will no longer receive new requests
  • It processes outstanding requests until its workload has been completed
  • Data is transferred to other nodes in the cluster
  • Only after all data has been transferred will the Operator turn down the node

SmartScaler is enabled by default.

Resource Management and Scaling

Horizontal Pod Autoscaling

Enable automatic scaling based on metrics:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: opensearch-data-hpa
spec:
  scaleTargetRef:
    apiVersion: opensearch.org/v1
    kind: OpenSearchCluster
    name: my-first-cluster
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Vertical Scaling

Update node resources:

# Scale up data node resources
kubectl patch opensearchcluster my-first-cluster --type='merge' -p='
{
  "spec": {
    "nodePools": [{
      "component": "data-nodes",
      "resources": {
        "requests": {
          "memory": "32Gi",
          "cpu": "8000m"
        },
        "limits": {
          "memory": "32Gi",
          "cpu": "8000m"
        }
      }
    }]
  }
}'

Storage Scaling

Increase persistent volume sizes:

spec:
  nodePools:
    - component: data-nodes
      persistence:
        pvc:
          size: "1Ti"  # Increased from 500Gi
          # Note: Requires storage class that supports volume expansion

Version Management and Rolling Updates

Controlled Rolling Updates

Configure update strategy:

spec:
  general:
    version: "2.15.0"
    drainDataNodes: true
  updateStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 0

Blue-Green Deployment

For zero-downtime major updates:

# Create new cluster with updated version
kubectl apply -f opensearch-cluster-v2.yaml

# Migrate data using reindex API
curl -X POST "https://old-cluster:9200/_reindex" \
  -H 'Content-Type: application/json' \
  -d '{
    "source": {
      "remote": {
        "host": "https://old-cluster:9200"
      },
      "index": "source-index"
    },
    "dest": {
      "index": "dest-index"
    }
  }'

# Switch traffic to new cluster
# Delete old cluster after verification

Production Considerations

Validation Webhooks

The operator includes admission controller webhooks that validate OpenSearch CRDs before they are applied. This prevents dangerous operations from reaching the cluster. Webhooks are enabled by default when installing via Helm.

High Availability and Resilience

Default Pod Anti-Affinity

By default, the operator applies pod anti-affinity rules to prevent multiple pods from the same OpenSearch cluster from being scheduled on the same node. This improves high availability without additional configuration. You can override this behavior by explicitly setting the affinity field in your node pool configuration.

Multi-Zone Deployment

Distribute nodes across availability zones for fault tolerance:

spec:
  nodePools:
    - component: masters
      replicas: 3
      nodeSelector:
        topology.kubernetes.io/zone: us-west-2a
    - component: masters-zone-b
      replicas: 3
      nodeSelector:
        topology.kubernetes.io/zone: us-west-2b
    - component: masters-zone-c
      replicas: 3
      nodeSelector:
        topology.kubernetes.io/zone: us-west-2c

Pod Disruption Budgets

The operator supports configuring PDBs per node pool directly in the cluster spec:

spec:
  nodePools:
    - component: masters
      replicas: 3
      diskSize: "30Gi"
      pdb:
        enable: true
        minAvailable: 2
      roles:
        - "cluster_manager"
    - component: data-nodes
      replicas: 5
      diskSize: "100Gi"
      pdb:
        enable: true
        maxUnavailable: 1
      roles:
        - "data"

You must provide either minAvailable or maxUnavailable, but not both.

Resource Quotas and Limits

Set cluster-wide resource constraints:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: opensearch-quota
spec:
  hard:
    requests.cpu: "50"
    requests.memory: 200Gi
    limits.cpu: "100"
    limits.memory: 400Gi
    persistentvolumeclaims: "20"

Init Containers

Add custom init containers to run before OpenSearch starts:

spec:
  nodePools:
    - component: masters
      replicas: 3
      initContainers:
        - name: init-sysctl
          image: busybox:latest
          command: ["sysctl", "-w", "vm.max_map_count=262144"]
          securityContext:
            privileged: true

Sidecar Containers

You can deploy additional sidecar containers alongside OpenSearch in the same pod for log shipping, monitoring agents, or other auxiliary services:

spec:
  nodePools:
    - component: masters
      replicas: 3
      sidecarContainers:
        - name: log-shipper
          image: fluent/fluent-bit:latest
          resources:
            requests:
              memory: "64Mi"
              cpu: "100m"
          volumeMounts:
            - name: varlog
              mountPath: /var/log

Additional Volumes

Mount ConfigMaps, Secrets, emptyDir, projected volumes, CSI volumes, or NFS volumes into OpenSearch pods:

spec:
  general:
    additionalVolumes:
      - name: example-configmap
        path: /path/to/mount/volume
        configMap:
          name: config-map-name
        restartPods: true  # Restart pods when configMap changes
      - name: nfs-backups
        path: /mnt/backups/opensearch
        nfs:
          server: 192.168.1.233
          path: /export/backups/opensearch
          readOnly: false

Host Aliases

Add custom entries to pod /etc/hosts files:

spec:
  general:
    hostAliases:
      - hostnames:
          - example.com
        ip: 127.0.0.1
  dashboards:
    hostAliases:
      - hostnames:
          - dashboard.example.com
        ip: 10.0.0.1

Security Hardening

Network Policies

Implement network segmentation:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: opensearch-network-policy
spec:
  podSelector:
    matchLabels:
      app: opensearch
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: opensearch
    - podSelector:
        matchLabels:
          app: kibana
    ports:
    - protocol: TCP
      port: 9200
    - protocol: TCP
      port: 9300
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: opensearch
    ports:
    - protocol: TCP
      port: 9300

RBAC Configuration

Configure Role-Based Access Control:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: opensearch-operator
  namespace: opensearch-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: opensearch-operator
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps", "secrets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
  resources: ["deployments", "statefulsets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: opensearch-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: opensearch-operator
subjects:
- kind: ServiceAccount
  name: opensearch-operator
  namespace: opensearch-system

Managing Resources via CRDs

The operator provides custom Kubernetes resources to manage OpenSearch security configurations and policies as Kubernetes objects.

Users, Roles, and Role Bindings

apiVersion: opensearch.org/v1
kind: OpensearchUser
metadata:
  name: sample-user
spec:
  opensearchCluster:
    name: my-first-cluster
  passwordFrom:
    name: sample-user-password
    key: password
  backendRoles:
    - kibanauser
---
apiVersion: opensearch.org/v1
kind: OpensearchRole
metadata:
  name: sample-role
spec:
  opensearchCluster:
    name: my-first-cluster
  clusterPermissions:
    - cluster_composite_ops
  indexPermissions:
    - indexPatterns:
        - logs*
      allowedActions:
        - index
        - read
---
apiVersion: opensearch.org/v1
kind: OpensearchUserRoleBinding
metadata:
  name: sample-urb
spec:
  opensearchCluster:
    name: my-first-cluster
  users:
    - sample-user
  roles:
    - sample-role

ISM Policies

apiVersion: opensearch.org/v1
kind: OpenSearchISMPolicy
metadata:
  name: logs-policy
spec:
  opensearchCluster:
    name: my-first-cluster
  policyId: logs-policy
  defaultState: hot
  states:
    - name: hot
      transitions:
        - stateName: warm
          conditions:
            minIndexAge: "7d"
    - name: warm
      actions:
        - replicaCount:
            numberOfReplicas: 0
      transitions:
        - stateName: delete
          conditions:
            minIndexAge: "30d"
    - name: delete
      actions:
        - delete: {}

Index and Component Templates

apiVersion: opensearch.org/v1
kind: OpensearchIndexTemplate
metadata:
  name: logs-template
spec:
  opensearchCluster:
    name: my-first-cluster
  indexPatterns:
    - "logs-*"
  template:
    settings:
      number_of_shards: 2
      number_of_replicas: 1

Additional CRDs

The operator also supports:

  • OpensearchActionGroup - Manage action groups
  • OpensearchTenant - Manage tenants
  • OpensearchComponentTemplate - Manage component templates
  • OpensearchSnapshotPolicy - Manage snapshot lifecycle policies

Environment Variables

Add custom environment variables to OpenSearch or Dashboards pods:

spec:
  dashboards:
    env:
      - name: MY_ENV_VAR
        value: "myvalue"
      - name: MY_SECRET_VAR
        valueFrom:
          secretKeyRef:
            name: my-secret
            key: some_key
  nodePools:
    - component: nodes
      env:
        - name: MY_ENV_VAR
          value: "myvalue"

Monitoring and Observability

Prometheus Integration

Enable metrics collection using the built-in Prometheus exporter plugin:

apiVersion: opensearch.org/v1
kind: OpenSearchCluster
metadata:
  name: my-first-cluster
spec:
  general:
    version: 3
    monitoring:
      enable: true
      scrapeInterval: 30s
      labels:
        release: prometheus
      # monitoringUserSecret: monitoring-user  # Optional: custom user for metrics access

The operator automatically installs the Prometheus exporter plugin and generates a ServiceMonitor for scraping.

Grafana Dashboard

Import pre-built dashboards for visualization:

# Download official OpenSearch Grafana dashboard
curl -o opensearch-dashboard.json \
  https://raw.githubusercontent.com/opensearch-project/opensearch-k8s-operator/main/grafana/opensearch-cluster-dashboard.json

# Import to Grafana
kubectl create configmap opensearch-dashboard \
  --from-file=opensearch-dashboard.json \
  -n monitoring

Log Management

Configure centralized logging:

spec:
  general:
    additionalConfig:
      log4j2.properties: |
        appender.console.type = Console
        appender.console.name = console
        appender.console.layout.type = PatternLayout
        appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n

        appender.json.type = Console
        appender.json.name = json
        appender.json.layout.type = ESJsonLayout
        appender.json.layout.type_name = server

        rootLogger.level = info
        rootLogger.appenderRef.console.ref = console
        rootLogger.appenderRef.json.ref = json

Health Checks and Alerts

Configure monitoring alerts:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: opensearch-alerts
spec:
  groups:
  - name: opensearch.rules
    rules:
    - alert: OpenSearchClusterRed
      expr: opensearch_cluster_status{color="red"} == 1
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "OpenSearch cluster status is RED"
        description: "Cluster  is in RED state"

    - alert: OpenSearchNodeDown
      expr: up{job="opensearch"} == 0
      for: 2m
      labels:
        severity: warning
      annotations:
        summary: "OpenSearch node is down"
        description: "Node  has been down for more than 2 minutes"

    - alert: OpenSearchDiskSpaceHigh
      expr: opensearch_filesystem_data_used_percent > 85
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "OpenSearch disk space usage high"
        description: "Disk usage on  is above 85%"

Best Practices

Performance Optimization

Configurable Probes

Customize startup, liveness, and readiness probe timeouts and thresholds per node pool:

spec:
  nodePools:
    - component: masters
      replicas: 3
      probes:
        liveness:
          initialDelaySeconds: 10
          periodSeconds: 20
          timeoutSeconds: 5
          failureThreshold: 10
        startup:
          initialDelaySeconds: 10
          periodSeconds: 20
          failureThreshold: 30
        readiness:
          initialDelaySeconds: 60
          periodSeconds: 30
          timeoutSeconds: 30

JVM Tuning

Optimize Java Virtual Machine settings:

spec:
  nodePools:
    - component: data-nodes
      jvm: |
        -Xms16g
        -Xmx16g
        -XX:+UseG1GC
        -XX:G1HeapRegionSize=32m
        -XX:+UseG1GC
        -XX:MaxGCPauseMillis=200
        -XX:+UnlockExperimentalVMOptions
        -XX:+UseTransparentHugePages
        -XX:+AlwaysPreTouch

Index Templates and Policies

Configure index lifecycle management:

# Create index template
curl -X PUT "https://localhost:9200/_index_template/logs_template" \
  -H 'Content-Type: application/json' \
  -d '{
    "index_patterns": ["logs-*"],
    "template": {
      "settings": {
        "number_of_shards": 2,
        "number_of_replicas": 1,
        "index.refresh_interval": "30s",
        "index.codec": "best_compression"
      },
      "mappings": {
        "properties": {
          "@timestamp": {
            "type": "date"
          },
          "message": {
            "type": "text",
            "analyzer": "standard"
          }
        }
      }
    }
  }'

# Create ISM policy for log rotation
curl -X PUT "https://localhost:9200/_plugins/_ism/policies/logs_policy" \
  -H 'Content-Type: application/json' \
  -d '{
    "policy": {
      "description": "Log rotation policy",
      "default_state": "hot",
      "states": [
        {
          "name": "hot",
          "actions": [],
          "transitions": [
            {
              "state_name": "warm",
              "conditions": {
                "min_index_age": "7d"
              }
            }
          ]
        },
        {
          "name": "warm",
          "actions": [
            {
              "replica_count": {
                "number_of_replicas": 0
              }
            }
          ],
          "transitions": [
            {
              "state_name": "delete",
              "conditions": {
                "min_index_age": "30d"
              }
            }
          ]
        },
        {
          "name": "delete",
          "actions": [
            {
              "delete": {}
            }
          ]
        }
      ]
    }
  }'

Backup and Disaster Recovery

Snapshot Configuration

Configure automated backups:

spec:
  general:
    additionalConfig:
      opensearch.yml: |
        path.repo: ["/usr/share/opensearch/snapshots"]
        repositories.s3.bucket: "opensearch-backups"
        repositories.s3.region: "us-west-2"

Backup Script

#!/bin/bash
# Automated backup script

CLUSTER_URL="https://localhost:9200"
ADMIN_USER="admin"
ADMIN_PASS="$OPENSEARCH_ADMIN_PASSWORD"
REPO_NAME="s3_repository"
SNAPSHOT_NAME="snapshot_$(date +%Y%m%d_%H%M%S)"

# Create repository if not exists
curl -k -u ${ADMIN_USER}:${ADMIN_PASS} -X PUT "${CLUSTER_URL}/_snapshot/${REPO_NAME}" \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "s3",
    "settings": {
      "bucket": "opensearch-backups",
      "region": "us-west-2",
      "base_path": "snapshots"
    }
  }'

# Create snapshot
curl -k -u ${ADMIN_USER}:${ADMIN_PASS} -X PUT "${CLUSTER_URL}/_snapshot/${REPO_NAME}/${SNAPSHOT_NAME}" \
  -H 'Content-Type: application/json' \
  -d '{
    "indices": "*",
    "ignore_unavailable": true,
    "include_global_state": false
  }'

echo "Snapshot ${SNAPSHOT_NAME} created successfully"

FAQ

General Questions

Q: What's the difference between OpenSearch and Elasticsearch? A: OpenSearch is an open-source fork of Elasticsearch, created after Elastic changed its license. It maintains API compatibility while being fully open-source under Apache 2.0 license.

Q: Can I migrate from Elasticsearch to OpenSearch? A: Yes, OpenSearch maintains API compatibility with Elasticsearch versions up to 7.10. Migration typically involves updating client configurations and reindexing data.

Q: What Kubernetes versions are supported? A: The operator supports Kubernetes 1.19 and later versions. It's tested on major cloud platforms including AWS EKS, Google GKE, and Azure AKS.

Q: What OpenSearch versions are supported? A: Operator versions 2.8.0 and 3.0.0 support OpenSearch 2.19.2 through the latest 3.x versions. Earlier operator versions (2.7.0 and below) support OpenSearch 1.3.x through 2.19.2.

Operational Questions

Q: How do I handle node failures? A: The operator automatically detects and replaces failed nodes. Ensure you have proper replica settings and the cluster will redistribute data automatically.

Q: Can I run multiple OpenSearch clusters in the same namespace? A: Yes, you can run multiple clusters in the same namespace by giving them unique names. Each cluster is isolated and managed independently.

Q: How do I update the operator itself? A: Update the operator using Helm: helm upgrade opensearch-operator opensearch-operator/opensearch-operator

Performance Questions

Q: What are the recommended resource requirements? A: For production:

  • Master nodes: 2-4 CPU cores, 4-8GB RAM
  • Data nodes: 4-8 CPU cores, 16-64GB RAM
  • Storage: High-IOPS SSDs recommended

Q: How do I optimize for search performance? A: Use dedicated coordinating nodes, optimize index mappings, implement proper sharding strategy, and consider hot-warm-cold architecture for time-series data.

Q: What's the maximum cluster size supported? A: OpenSearch clusters can scale to hundreds of nodes. The operator has been tested with clusters up to 100 nodes, but larger deployments are possible with proper planning.

Troubleshooting

Common Issues and Solutions

Pod Startup Issues

Problem: Pods stuck in Pending state

# Check node resources
kubectl describe nodes
kubectl top nodes

# Check pod events
kubectl describe pod <pod-name>

# Check resource quotas
kubectl describe resourcequota

Solution: Ensure sufficient node resources or adjust resource requests.

Cluster Formation Issues

Problem: Nodes not joining cluster

# Check cluster logs
kubectl logs -l opensearch.role=master

# Verify network connectivity
kubectl exec -it <pod-name> -- curl -k https://<other-pod-ip>:9200

Solution: Verify network policies and service discovery configuration.

Storage Issues

Problem: Persistent volume claim failures

# Check PVC status
kubectl get pvc
kubectl describe pvc <pvc-name>

# Check storage class
kubectl get storageclass

Solution: Ensure storage class supports dynamic provisioning and has sufficient capacity.

Debug Commands

# Get all OpenSearch resources
kubectl get opensearchclusters,pods,services,pvc -l opensearch.org/opensearch-cluster=my-first-cluster

# Check operator logs
kubectl logs -l app.kubernetes.io/name=opensearch-operator -f

# Exec into OpenSearch pod
kubectl exec -it <pod-name> -- /bin/bash

# Port forward for direct access
kubectl port-forward svc/<service-name> 9200:9200

# Get cluster configuration
curl -k -u admin:$PASSWORD https://localhost:9200/_cluster/settings?pretty

# Check allocation explain
curl -k -u admin:$PASSWORD https://localhost:9200/_cluster/allocation/explain?pretty

Cleanup and Uninstallation

Remove OpenSearch Cluster

# Delete cluster (data will be preserved in PVCs)
kubectl delete opensearchcluster my-first-cluster

# Delete PVCs to remove data permanently
kubectl delete pvc -l opensearch.org/opensearch-cluster=my-first-cluster

Uninstall Operator

# Remove operator
helm uninstall opensearch-operator

# Clean up CRDs (optional) - remove both old and new API group CRDs
kubectl delete crd opensearchclusters.opensearch.org
kubectl delete crd opensearchclusters.opensearch.opster.io  # If migrating from old version

# Remove operator namespace (if using namespace-scoped installation)
kubectl delete namespace opensearch-operator-system

Enterprise Support

Need help with your OpenSearch deployment? Our team provides enterprise-grade support for OpenSearch clusters, including architecture planning, performance optimization, security hardening, and 24/7 incident response.

Learn more about OpenSearch Enterprise Support

Pulse - Elasticsearch Operations Done Right

Pulse can solve your OpenSearch issues

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.