OpenSearch Cluster with Docker Compose: Setup and Security - 夜莺博客

OpenSearch Cluster with Docker Compose: Setup and Security

OpenSearch is the Apache-licensed fork of Elasticsearch with a bundled security plugin and dashboards, which makes it a reasonable default for self-hosted log analytics. Running it under Docker Compose is the fastest way to a working cluster, and also the fastest way to ship something insecure — the default demo configuration uses published credentials. This guide builds a two-node cluster correctly, sizes the JVM heap, and explains when to move from demo security to your own certificates.

The compose file that matters

services:
  opensearch-node1:
    image: opensearchproject/opensearch:3.8.0
    container_name: opensearch-node1
    environment:
      - cluster.name=opensearch-cluster
      - node.name=opensearch-node1
      - discovery.seed_hosts=opensearch-node1,opensearch-node2
      - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2
      - bootstrap.memory_lock=true
      - "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g"
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD}
    ulimits:
      memlock: {soft: -1, hard: -1}
      nofile: {soft: 65536, hard: 65536}
    volumes:
      - opensearch-data1:/usr/share/opensearch/data
    ports:
      - 9201:9200
      - 9600:9600
    networks: [opensearch-net]

  opensearch-node2:
    image: opensearchproject/opensearch:3.8.0
    container_name: opensearch-node2
    environment:
      - cluster.name=opensearch-cluster
      - node.name=opensearch-node2
      - discovery.seed_hosts=opensearch-node1,opensearch-node2
      - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2
      - bootstrap.memory_lock=true
      - "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g"
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD}
    ulimits:
      memlock: {soft: -1, hard: -1}
      nofile: {soft: 65536, hard: 65536}
    volumes:
      - opensearch-data2:/usr/share/opensearch/data
    networks: [opensearch-net]

  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:3.8.0
    container_name: opensearch-dashboards
    ports:
      - 5601:5601
    environment:
      OPENSEARCH_HOSTS: '["https://opensearch-node1:9200","https://opensearch-node2:9200"]'
    networks: [opensearch-net]

volumes:
  opensearch-data1:
  opensearch-data2:

networks:
  opensearch-net:

Every line above is load-bearing. cluster.initial_cluster_manager_nodes only applies on first boot — changing it later does nothing. bootstrap.memory_lock=true stops the JVM from being swapped out, and the corresponding memlock ulimit must be unlimited or the container refuses to start. nofile at 65536 covers the file descriptors a busy index needs.

JVM heap sizing

The guidance is to set both -Xms and -Xmx to the same value, at roughly half the container's memory, and never above 31 GB (which forces compressed ordinary object pointers off and degrades performance). Leaving heap at the 512 MB default on a production host is a common cause of constant garbage collection and slow queries.

Security: demo versus custom

Unless DISABLE_SECURITY_PLUGIN=true is set, the container runs a bundled script that installs a demo security configuration with well-known usernames and passwords. That is acceptable for a laptop and unacceptable for anything reachable. For a development stack, disable the plugin explicitly so it is obvious what you have done:

      - "DISABLE_INSTALL_DEMO_CONFIG=true"
      - "DISABLE_SECURITY_PLUGIN=true"

For production, mount your own configuration and certificates instead:

    volumes:
      - ./opensearch.yml:/usr/share/opensearch/config/opensearch.yml
      - ./root-ca.pem:/usr/share/opensearch/config/root-ca.pem
      - ./esnode.pem:/usr/share/opensearch/config/esnode.pem
      - ./esnode-key.pem:/usr/share/opensearch/config/esnode-key.pem
      - ./internal_users.yml:/usr/share/opensearch/config/opensearch-security/internal_users.yml
      - ./roles.yml:/usr/share/opensearch/config/opensearch-security/roles.yml
      - ./roles_mapping.yml:/usr/share/opensearch/config/opensearch-security/roles_mapping.yml
      - ./audit.yml:/usr/share/opensearch/config/opensearch-security/audit.yml

The certificates referenced in the compose file must match those named in opensearch.yml, and the distinguished name of the admin certificate must be declared in nodes_dn.yml for node-to-node authentication. Replace the root, admin and node certificates with your own; the demo certificates are shared publicly and provide no security at all.

Bring it up and verify

export OPENSEARCH_INITIAL_ADMIN_PASSWORD='<a strong password>'
docker compose up -d
docker compose ps

curl -k -u admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD https://localhost:9201/_cluster/health?pretty
curl -k -u admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD https://localhost:9201/_cat/nodes?v

Expect status: green with two data nodes. Yellow on a fresh cluster usually means replica shards have nowhere to go — with two nodes and default replica counts, some indices cannot be fully replicated, which is normal and not a fault. Red means a primary shard is unassigned, and the recovery path is the same as for the Elasticsearch lineage covered in Elasticsearch red and yellow cluster shards.

Before going live, pin image versions rather than using latest so a restart does not silently upgrade the cluster mid-incident, back up the security configuration, and decide early how logs will reach the cluster — a network-telemetry ingest design is described in ClickHouse for network telemetry.

原文链接:https://docs.opensearch.org/latest/install-and-configure/install-opensearch/docker/