ویرگول
ورودثبت نام
Amirhossein Maleki
Amirhossein Maleki
Amirhossein Maleki
Amirhossein Maleki
خواندن ۳ دقیقه·۳ ماه پیش

راه‌اندازی کلاستر Elasticsearch

در یکی از سناریوها، تصمیم گرفتم یک کلاستر Elasticsearch راه‌اندازی کنم؛ اما نه با Docker یا ماشین مجازی. هدف ما ایجاد محیطی بود که در عین سادگی، امن، پایدار و کاملاً سازگار با SELinux باشد.
انتخابم: Podman روی Rocky Linux — ترکیبی سبک، بدون daemon و مناسب برای سرویس‌های حیاتی.


راه اندازی Elasticsearch Cluster
راه اندازی Elasticsearch Cluster

چرا کلاستر؟ و چرا سه نود؟

Elasticsearch برای معماری توزیع‌شده طراحی شده است. اما در حالت تک‌نودی نه مقیاس‌پذیری دارد و نه تحمل خطا.

در یک محیط چندنودی:

  • داده‌ها به‌صورت shard و replica بین نودها پخش می‌شوند.

  • خرابی یک نود باعث از کار افتادن سرویس نمی‌شود.

  • ایندکس‌گذاری و query به‌صورت موازی انجام می‌شوند.

از سه نود استفاده کردم: یک نود master و دو نود data. این ترکیب حداقل ساختاری است که quorum را تضمین می‌کند؛ یعنی اگر یکی از نودها از دسترس خارج شود، دو نود دیگر همچنان قادر به ادامه کار و حفظ هماهنگی هستند.

در محیط‌های تولیدی بزرگ‌تر، داشتن سه master اختصاصی و چند data node مجزا توصیه می‌شود.


امنیت و TLS بین نودها

اولین گام، فعال‌سازی ارتباط امن بین نودهاست. برای این کار از ابزار داخلی elasticsearch-certutil استفاده کردم تا برای هر نود گواهی و کلید اختصاصی تولید شود:

bin/elasticsearch-certutil cert --silent --pem \ --in config/instances.yml \ --ca-cert config/certs/ca/ca.crt \ --ca-key config/certs/ca/ca.key \ --out config/certs/certs.zip unzip config/certs/certs.zip -d config/certs/

فایل instances.yml باید شامل IP و نام هر نود باشد:

instances: - name: "master-node" ip: ["<MASTER_IP>"] - name: "data-node-01" ip: ["<DATA_NODE_01_IP>"] - name: "data-node-02" ip: ["<DATA_NODE_02_IP>"]

نتیجه: هر نود گواهی و کلید مخصوص خود را دارد، در حالی‌که همه از یک CA مشترک استفاده می‌کنند.


پیکربندی نود Master

cluster.name: es-cluster node.name: master-node discovery.seed_hosts: ["<MASTER_IP>", "<DATA_NODE_01_IP>", "<DATA_NODE_02_IP>"] cluster.initial_master_nodes: ["master-node"] network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 xpack.security.enabled: true # HTTP TLS xpack.security.http.ssl.enabled: true xpack.security.http.ssl.key: certs/master-node/key.pem xpack.security.http.ssl.certificate: certs/master-node/crt.pem xpack.security.http.ssl.certificate_authorities: ["certs/ca/ca.crt"] # Transport TLS xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.key: certs/master-node/key.pem xpack.security.transport.ssl.certificate: certs/master-node/crt.pem xpack.security.transport.ssl.certificate_authorities: ["certs/ca/ca.crt"] xpack.security.transport.ssl.verification_mode: certificate node.roles: [ master, data, ingest ]

در این سناریو به دلیل محدودیت منابع، master نقش data و ingest را هم دارد. در محیط‌های production این نقش‌ها باید از هم جدا باشند.


SELinux و مجوزها در Rocky Linux

Podman به‌طور پیش‌فرض با SELinux سازگار است. اگر context فایل‌ها اشتباه باشد، کانتینرها نمی‌توانند به config یا cert دسترسی پیدا کنند.

sudo chcon -t container_file_t ~/es-config/elasticsearch.yml sudo chcon -R -t container_file_t ~/es-certs sudo chmod 644 ~/es-config/elasticsearch.yml sudo chmod -R 755 ~/es-certs sudo chown -R $(whoami):$(whoami) ~/es-config ~/es-certs

اجرای Elasticsearch با Podman

podman volume create es-data podman run -d --name elasticsearch \ --network=host \ --security-opt label=disable \ -v es-data:/usr/share/elasticsearch/data \ -v ~/es-config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro \ -v ~/es-certs:/usr/share/elasticsearch/config/certs:ro \ docker.io/library/elasticsearch:8.12.0 sleep 60 && podman logs -f elasticsearch

نکته: در محیط‌های امن‌تر، بهتر است به‌جای network=host-- از شبکه جداگانه (bridge یا CNI) استفاده شود.


اتصال Kibana با Service Token

به‌جای ذخیره رمز عبور کاربر در فایل پیکربندی، از Service Token استفاده کردم:

TOKEN=$(curl -s -k -u elastic:<PASSWORD> -X POST \ "https://<MASTER_IP>:9200/_security/service/elastic/kibana/credential/token/kibana-svc" \ -H "Content-Type: application/json" | jq -r .value)

و سپس در فایل kibana.yml:

elasticsearch.hosts: ["https://<MASTER_IP>:9200"] elasticsearch.serviceAccountToken: "$TOKEN" elasticsearch.ssl.certificateAuthorities: ["/usr/share/kibana/config/certs/ca/ca.crt"] server.ssl.enabled: true server.ssl.certificate: /usr/share/kibana/config/certs/master-node/master-node.crt server.ssl.key: /usr/share/kibana/config/certs/master-node/master-node.key

اجرای Kibana:

podman run -d --name kibana \ --network=host \ --security-opt label=disable \ -v ~/kibana-config/kibana.yml:/usr/share/kibana/config/kibana.yml:ro \ -v ~/es-certs:/usr/share/kibana/config/certs:ro \ docker.io/library/kibana:8.12.0

پیکربندی نودهای Data

node.name: data-node-01 node.roles: [ data, ingest ] xpack.security.http.ssl.key: certs/data-node-01/key.pem xpack.security.http.ssl.certificate: certs/data-node-01/crt.pem ES_JAVA_OPTS: "-Xms2g -Xmx2g"

نام نود و مسیر گواهی باید دقیقاً با فایل instances.yml یکسان باشد.


تنظیمات حیاتی سیستم و JVM

sysctl -w vm.max_map_count=262144 ulimit -n 65535

در elasticsearch.yml:

cluster.routing.allocation.disk.watermark.low: 85% cluster.routing.allocation.disk.watermark.high: 90%

و برای حافظه JVM:

ES_JAVA_OPTS="-Xms2g -Xmx2g"

قانون کلی: حداکثر نیمی از RAM سیستم و حداکثر 32GB برای heap.


نکات نگهداری و عملیات

  1. Snapshots به S3 یا فایل‌سیستم خارجی برای Disaster Recovery

  2. Monitoring با X-Pack یا Prometheus Exporter

  3. Rolling Restart — همیشه نودها را یکی‌یکی بازنشانی کنید

  4. ILM برای مدیریت چرخه عمر شاخص‌ها و کنترل رشد حجم

  5. Allocation Awareness در محیط‌های چند zone یا چند host

اجرا شد. Podman در این سناریو جایگزین قابل اتکایی برای Docker بود، با کنترل امنیتی بهتر و سازگاری بیشتر در محیط‌های Enterprise.

برای تیم‌هایی که به دنبال ترکیبی از سادگی، امنیت و پایداری هستند، Elasticsearch + Podman + Rocky Linux می‌تواند معماری‌ای پایدار و منعطف بسازد.


#Elasticsearch #Podman #DevOps #Security #Linux #RockyLinux #SystemDesign #Infrastructure #Kibana #Containers

elasticsearchkibanaclusteringdevops
۳
۰
Amirhossein Maleki
Amirhossein Maleki
شاید از این پست‌ها خوشتان بیاید