콘텐츠로 이동

ElasticSearch 설치

ELK 스택 또는 elastic.co 같은 관리형 서비스 ELK 스택이나 AWS 또는 기타 클라우드 제공업체의 Elasticsearch 인스턴스.

  • ElasticSearch 버전: 7.8.1 이상 (8.x 권장)
  • 최소 노드 수: 3개 (고가용성)
  • 메모리: 노드당 최소 8GB (16GB 권장)
  • 스토리지: 노드당 최소 200GB SSD
  • 네트워크: 1Gbps 이상
/etc/elasticsearch/jvm.options
-Xms8g
-Xmx8g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=400
-XX:+UseStringDeduplication
Terminal window
helm repo add elastic https://helm.elastic.co
helm repo update
elasticsearch-values.yaml
replicas: 3
minimumMasterNodes: 2
# JVM 힙 크기
esJavaOpts: "-Xmx8g -Xms8g"
# 리소스 제한
resources:
requests:
cpu: "2"
memory: "16Gi"
limits:
cpu: "4"
memory: "16Gi"
# 영구 볼륨
persistence:
enabled: true
size: "200Gi"
storageClass: "fast-ssd"
# 보안 설정
extraEnvs:
- name: ELASTIC_PASSWORD
valueFrom:
secretKeyRef:
name: elastic-credentials
key: password
# 클러스터 설정
esConfig:
elasticsearch.yml: |
cluster.name: "doverunner-es"
network.host: 0.0.0.0
# 보안 설정
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.enabled: true
# 성능 최적화
indices.memory.index_buffer_size: 20%
indices.queries.cache.size: 20%
thread_pool.write.queue_size: 1000
# 로그 정책
action.destructive_requires_name: true
cluster.routing.allocation.disk.threshold.enabled: true
cluster.routing.allocation.disk.watermark.low: 85%
cluster.routing.allocation.disk.watermark.high: 90%
cluster.routing.allocation.disk.watermark.flood_stage: 95%
# 서비스 타입
service:
type: ClusterIP
port: 9200
nodePort: ""
# 네트워크 정책
networkPolicy:
enabled: true
allowExternal: false
Terminal window
# Secret 생성
kubectl create secret generic elastic-credentials \
--from-literal=password=your-secure-password \
--namespace=doverunner
# Elasticsearch 설치
helm install elasticsearch elastic/elasticsearch \
--namespace=doverunner \
--values=elasticsearch-values.yaml \
--wait --timeout=10m

인덱스 라이프사이클 정책 설정

Section titled “인덱스 라이프사이클 정책 설정”
PUT _ilm/policy/doverunner-logs-policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "10GB",
"max_age": "1d"
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"allocate": {
"number_of_replicas": 0
},
"forcemerge": {
"max_num_segments": 1
},
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"allocate": {
"number_of_replicas": 0
},
"set_priority": {
"priority": 0
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}
PUT _ilm/policy/security-logs-policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "5GB",
"max_age": "12h"
},
"set_priority": {
"priority": 200
}
}
},
"warm": {
"min_age": "3d",
"actions": {
"allocate": {
"number_of_replicas": 1
},
"set_priority": {
"priority": 100
}
}
},
"cold": {
"min_age": "90d",
"actions": {
"allocate": {
"number_of_replicas": 0
}
}
},
"delete": {
"min_age": "365d",
"actions": {
"delete": {}
}
}
}
}
}
PUT _index_template/doverunner-logs-template
{
"index_patterns": [
"doverunner-logs-*"
],
"template": {
"settings": {
"number_of_shards": 2,
"number_of_replicas": 1,
"index.lifecycle.name": "doverunner-logs-policy",
"index.lifecycle.rollover_alias": "doverunner-logs",
"refresh_interval": "30s",
"index.mapping.total_fields.limit": 2000
},
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
},
"level": {
"type": "keyword"
},
"message": {
"type": "text",
"analyzer": "standard"
},
"service": {
"type": "keyword"
},
"host": {
"type": "keyword"
},
"user_id": {
"type": "keyword"
},
"session_id": {
"type": "keyword"
},
"ip_address": {
"type": "ip"
},
"user_agent": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"priority": 100,
"composed_of": [],
"version": 1,
"_meta": {
"description": "Template for DoveRunner general logs"
}
}
PUT _index_template/security-logs-template
{
"index_patterns": [
"security-logs-*"
],
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"index.lifecycle.name": "security-logs-policy",
"index.lifecycle.rollover_alias": "security-logs",
"refresh_interval": "5s"
},
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
},
"device_id": {
"type": "keyword"
},
"app_package": {
"type": "keyword"
},
"threat_type": {
"type": "keyword"
},
"threat_level": {
"type": "keyword"
},
"location": {
"type": "geo_point"
},
"device_info": {
"properties": {
"model": {
"type": "keyword"
},
"os_version": {
"type": "keyword"
},
"is_rooted": {
"type": "boolean"
}
}
},
"threat_details": {
"type": "object",
"enabled": false
}
}
}
},
"priority": 200,
"_meta": {
"description": "Template for security threat logs"
}
}
# 일반 로그 인덱스
PUT doverunner-logs-000001
{
"aliases": {
"doverunner-logs": {
"is_write_index": true
}
}
}
# 보안 로그 인덱스
PUT security-logs-000001
{
"aliases": {
"security-logs": {
"is_write_index": true
}
}
}
# 읽기 전용 별칭 (분석용)
PUT doverunner-logs-read
{
"aliases": {
"doverunner-logs-readonly": {}
}
}
PUT _rollup/job/daily-stats-rollup
{
"index_pattern": "doverunner-logs-*",
"rollup_index": "rollup-daily-stats",
"cron": "0 0 * * * ?",
"page_size": 1000,
"groups": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "1d",
"time_zone": "Asia/Seoul"
},
"terms": {
"fields": ["service", "level", "app_package"]
}
},
"metrics": [
{
"field": "response_time",
"metrics": ["avg", "max", "min", "sum"]
},
{
"field": "request_count",
"metrics": ["sum", "value_count"]
}
]
}
PUT _rollup/job/security-summary-rollup
{
"index_pattern": "security-logs-*",
"rollup_index": "rollup-security-summary",
"cron": "0 */6 * * * ?",
"page_size": 1000,
"groups": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "1h"
},
"terms": {
"fields": ["threat_type", "threat_level", "app_package"]
}
},
"metrics": [
{
"field": "threat_count",
"metrics": ["sum", "value_count"]
}
]
}
PUT _cluster/settings
{
"persistent": {
"indices.recovery.max_bytes_per_sec": "100mb",
"cluster.routing.allocation.cluster_concurrent_rebalance": 2,
"cluster.routing.allocation.node_concurrent_recoveries": 2,
"cluster.routing.allocation.awareness.attributes": "zone",
"indices.store.throttle.max_bytes_per_sec": "100mb"
}
}
# elasticsearch.yml에 추가
node.attr.zone: zone1
node.attr.temp: hot # hot, warm, cold 중 하나
elasticsearch-exporter.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: elasticsearch-exporter
namespace: doverunner
spec:
replicas: 1
selector:
matchLabels:
app: elasticsearch-exporter
template:
metadata:
labels:
app: elasticsearch-exporter
spec:
containers:
- name: elasticsearch-exporter
image: quay.io/prometheuscommunity/elasticsearch-exporter:latest
ports:
- containerPort: 9114
env:
- name: ES_URI
value: "http://elasticsearch:9200"
- name: ES_ALL
value: "true"
- name: ES_INDICES
value: "true"
- name: ES_SHARDS
value: "true"
Terminal window
# Kibana values.yaml
elasticsearchHosts: "http://elasticsearch:9200"
replicas: 1
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
service:
type: ClusterIP
port: 5601
ingress:
enabled: true
hosts:
- host: kibana.yourdomain.com
paths:
- path: /
# 설치
helm install kibana elastic/kibana \
--namespace=doverunner \
--values=kibana-values.yaml
PUT _snapshot/backup-repo
{
"type": "s3",
"settings": {
"bucket": "doverunner-es-backups",
"region": "ap-northeast-2",
"base_path": "elasticsearch-snapshots",
"compress": true
}
}
PUT _slm/policy/daily-backup
{
"schedule": "0 30 1 * * ?",
"name": "<daily-snap-{now/d}>",
"repository": "backup-repo",
"config": {
"indices": ["doverunner-logs-*", "security-logs-*"],
"ignore_unavailable": false,
"include_global_state": false
},
"retention": {
"expire_after": "30d",
"min_count": 5,
"max_count": 50
}
}

이 가이드를 따르면 DoveRunner Mobile App Security와 완전히 통합된 고성능 ElasticSearch 클러스터를 구축할 수 있습니다.