[엘라스틱서치 바이블] 5. 서비스 환경에 클러스터 구성
5.1 운영 환경을 위한 설정과 클러스터 구성
5.1.1 노드 설정과 노드 역할
- ES 클러스터 내에서 각 노드가 수행하는 역할의 종류에 대해 알아보자
노드 역할
- 클러스터 구성시 반드시 노드에 역할을 지정해야 한다.
- 지정된 역할에 따라 노드가 클러스터 내에서 어떤 작업을 담당할지 정해진다.
마스터 후보(master-eligible) 노드
- 노드의 역할에 master를 지정하면 해당 노드는 마스터 후보 노드가 된다.
- 마스터 후보 노드 중에서 선거를 통해 마스터 노드가 선출된다.
- 마스터 노드는 클러스터를 관리하는 역할을 수행한다.
- 인덳 생성이나 삭제, 어떤 샤드를 어느 노드에 할당할 것인지 등 중요한 작업을 수행한다.
데이터 노드
- 실제 데이터를 들고 있는 노드이다.
- CRUD, 검색, 집계와 같이 데이터와 관련된 작업을 수행한다.
인제스트(ingest) 노드
- 데이터가 색인되기 전에 전처리를 수행하는 인제스트 파이프라인을 수행하는 노드이다.
- 간략히 살펴보면 데이터(Document)가 파이프라인을 통해 들어올떄 lowercase와 같은 전처리 등을 수행한다고 보면 된다.
- 자세한 내용은 ES Doc Ingest 을 참고하자.
조정 노드
- 클라이언트의 요청을 받아서 다른 노드에 요청을 분배하고, 클라이언트에게 최종 응답을 돌려주는 노드이다.
- 기본적으로 모든 노드가 조정 노드 역할을 수행한다.
- 마스터나 데이터 등 주요 역할을 수행하지 않고, 조정 역할만 수행하는 노드는 조정 전용 노드라고 한다.
원격 클러스터 클라이언트 노드
- 다른 ES 클러스터에 클라이언트로 붙을 수 있는 노드이다.
- 노드 역할에
remote_cluster_client
을 추가해 지정한다. - 키바나의 스택 모니터링 기능을 활용해서 모니터링 전용 클러스ㅓ터를 구축한 뒤 얼럿 메시지를 보내도록 구성하거나 유료 기능인 클러스터간 검색 기능 등을 활용할 때 사용된다.
데이터 티어 노드
- 데이터 노드를 용도 및 성능별로 hot-warm-cold-frozen 티어로 구분해 저장하는 데이터 티어 구조 채택시 사용하는 역할이다.
- data 역할 대신에 data_content, data_hot, data_warm, data_cold, data_frozen 역할을 선택한다.
config/elasticsearch.yml
- 클러스터 구성시 위 confg 파일을 통해 설정을 할수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
node.roles: [data, master, ingest]
cluster.name: test-es
node.name: test-es-node01
http.port: 9200
transport.port: 9300-9400
network.host: my_server_ip
path:
data: /var/lib/elasticsearch/logs
logs:
- /var/log/elasticsearch/data1
- /var/log/elasticsearch/data2
network.host: 10.0.0.1
network.bind_host: 0.0.0.0
discovery.seed_hosts: ["10.0.0.1", "10.0.0.2", "some-host-name.net"]
cluster.initial_master_nodes: ["node_name-1", "node_name-2" "node_name-3"]
xpack.monitoring.enabled: false
node.roles
- 노드 역할을 지정한다. (master, data ,ingest 등)
- 0개 이상을 조합할 수 있다.
[]
와 같이 비워두면 조정 전용 노드가 된다.- 하나의 노드가 여러 역할을 할수 있으나, 운영 환경에서는 마스터 후보 역할과 데이터 역할을 분리하는 것이 좋다.
discovery.seed_hosts
- 마스터 노드로 동작할 수 있는 노드 목록을 지정한다.
cluster.initial_master_nodes
- 클러스터를 처음 기동할 떄 첫 마스터 선거를 수행할 후보 노드 목록을 지정한다. (node.name에 기입한 값)
network.bind_host, network.publish_post
- bind_host는 ES에 바인딩할 네트워크 주소를 지정한다.
- publish_post는 클러스터의 다른 노드에게 자신을 알릴 떄 쓰는 주소를 지정한다.
- network.host에 지정한 값을 입력한다.
tansport.port
- transport 통신을 위해 사용하는 포트를 지정한다.
path.data
- 데이터 디렉터리를 지정할 수 있다.
- 여러 경로를 지정할수 있는 부분은 7.13버전부터 지원 중단되었다.
5.1.2 그 외 필요한 주요 설정
힙 크기
- 적절한 힙 크기 지정은 ES 클러스터 운영에서 아주 중요하다.
- 힙 크기는
config/jvm.options
를 열어 다음과 같은 방식으로 지정한다.
1
2
3
4
vim config/jvm.options.d/heap-size.options
-Xms32736m
-Xmx32736m
힙 크기 지정 관련 대원칙
- 최소한 시스템 메모리의 절반 이하로 지정해야 한다. 시스템 메모리의 절반은 운영체제가 캐시로 쓰도록 놔두는것이 좋다.
- 루씬이 커널 시스템 캐시를 많이 활용하기 떄문이다.
- 최소한 시스템 메모리의 절반 이하로 지정해야 한다. 시스템 메모리의 절반은 운영체제가 캐시로 쓰도록 놔두는것이 좋다.
- 힙 크기를 32GB 이상 지정하지 않아야 한다.
- ES는 512GB 이상의 고용량 메모리를 갖춘 서버를 사용하더라도 힙 크기는 32GB 이하로 가이드한다.
- JVM이 힙 영역에 생성된 객체에 접근하기 위한 포인터(Ordinary Object Pointer)을 통해 처리되는데, 32비트 환경에서는 포인터 1개를 32비트로, 64비트 환경에서는 64비트로 표현하므로, 4GB를 넘어서는 힙을 사용한다면 32비트 OOP로는 불가능하고, 64비트 OOP를 사용하는 경우에도 최대 32GB까지만 가능하다.
- 다만, 32GB 이내 힙 영역에만 접근한다면 CompressedOOPs라는 기능을 적용해 포인터를 32비트로 유지할 수 있다. 하지만 정확한것은 확인을 통해 CompressedOOPs 값이 true가 되는 경계값으로 힙 크기를 지정해야 한다.
- 힙 크기를 32GB 이상 지정하지 않아야 한다.
1
2
3
4
5
java -Xmx32736m -XX:+PrintFlagsfinal 2> /dev/null | grep UseCompressedOops
java -Xmx32737m -XX:+PrintFlagsfinal 2> /dev/null | grep UseCompressedOops
java -XX:+UnlockDiagnosticVMOptions -Xlog:gc+heap+coops=debug -Xmx30721m -version
java -XX:+UnlockDiagnosticVMOptions -Xlog:gc+heap+coops=debug -Xmx30720m -version
1
2
3
4
5
[0.002s][debug][gc,heap,coops] Protected page at the reserved heap base: 0x0000000280000000 / 16777216 bytes
[0.002s][debug][gc,heap,coops] Heap address: 0x0000000281000000, size: 30720 MB, Compressed Oops mode: Non-zero based: 0x0000000280000000, Oop shift amount: 3
openjdk version "17.0.6" 2023-01-17 LTS
OpenJDK Runtime Environment Zulu17.40+19-CA (build 17.0.6+10-LTS)
OpenJDK 64-Bit Server VM Zulu17.40+19-CA (build 17.0.6+10-LTS, mixed mode, sharing)
- 엄밀히 테스트하기 어렵다면
Compressed Oops mode
가Zero based
선까지 낮추는것을 권장한다.
스와핑
- ES는 스와핑을 사용하지 않도록 강력히 권고한다.
- 스와핑은 성능과 노드 안정성에 큰 영향을 미친다.
- ms단위로 끝나야 할 GC를 분 단위 시간까지 걸리게 만들기도 한다. 스와핑을 켜는것보다 차라리 OS가 노드를 kill 시키도록 놔두는것이 낫다고 가이드한다.
스와핑을 완전히 끄기
- 아래 명령어를 통해 OS의 스와핑을 완전히 끌수 있다.
- 이 명령 전후에 ES 노드를 재기동하지 않아도 되나, OS 재부팅 후에도 설정을 유지하고 싶다면
/etc/fstab
내부의swap
부분을 제거해야 한다.
1
2
3
sudo swapoff -a
sudo vim /etc/fstab
swapiness 설정
- 스와핑을 완전히 끌 수 없는 특수한 상황이라면
swapiness
값을 1로 설정하여 스와핑 경향성을 최소화할 수 있다.
1
2
3
4
5
6
7
8
sysctl vm.swappiness
vm.swappiness = 30
sudo sysctl -w vm.swappiness=1
# os 재부팅 후에도 유지시키고 싶다면 아래 파일 수정
sudo vim /etc/sysctl.d/98-elasticsearch.conf
vm.swappiness = 1
bootstrap.memory_lock 설정
bootstrap.memory_lock: true
설정을 지정하여 프로세스의 주소 공간을 메모리로 제한시키고, 스와핑되는것을 막을 수 있다. -그러나 이방법은 애플리케이션 레벨에서만 의미가 있는 제한적인 기술이다.(OS 차원에서 이 설정을 무시하고 스와핑이 발생할 수 있다.)
vm.max_map_count
vm.max_map_count
값은 프로세스가 최대 몇 개까지 메모리 맵 영역을 가질수 있는지를 지정한다.- 루씬은 mmap을 적극적으로 활용하기 떄문에
vm.max_map_count
값을 높일 필요가 있따. - 만약 이 값이 262144보다 작은 값으로 셋팅되어 있다면 ES는 기동 자첼가 되지 않을수 있다.
- 이 값의 설정은 최대치를 규정할 뿐이며, 값을 매우 높게 하더라도 OS 메모리 사용량이나 성능상 손해는 없다고 알려져있다.
- 일반적으로 추천되는 사이즈는
시스템의 메모리 / 128KB
의 값으로 셋팅하는것을 추천한다. - 대부분의 경우 262144로 지정해 대규모 ES 서비스를 운영해도 별 문제는 없다.
1
2
3
4
5
6
7
8
sysctl vm.max_map_count
vm.max_map_count = 65530
sudo sysctl v-w m.max_map_count=262144
# 재부팅 후에도 설정을 유지하려면 아래 파일 수정
sudo vim /etc/sysctl.d/98-elasticsearch.conf
vm.max_map_count = 262144
파일 기술자
- ES는 많은 파일 기술자(file descriptor)를 필요로 한다. ES는 이값을 최소 65535 이상으로 지정하도록 가이드한다.
1
2
3
4
5
6
7
8
9
10
11
ulimit -a | grep "open files"
# OSX에서는 아래설정으로 확인
ulimit -a | grep 'file descriptor'
# 값 설정
sudo ulimit -n 65535
# 영구 지정을 위해 파일 수정
sudo vim /etc/security/limits.conf
username - nofile 65535
JVM 지정과 설정
- 특별한 사유가 없다면 내장 JDK를 사용하는것이 좋으며, 힙 크기와 JVM 설정은 굳이 변경하지 않도록 권고한다.
- 7.12 버전 미만을 사용한다면 의도치 않은 JAVA_HOME 환경 변수가 설정됐는지 사전에 확인해야 하는 점도 동일하다.
5.2 클러스터 구성 전략
5.2.1 마스터 후보 노드와 데이터 노드를 분리
- 어느 정도 규모가 있는 서비스를 위해 클러스터를 운영한다면 마스터 후보 노드를 데이터 노드와 분리시켜야 한다.
- 마스터 노드는 클러스터를 관리하는 중요한 역할을 하는데 운영 중 발생하는 문제를 보면 상대적으로 데이터 노드가 죽을 확률이 높으므로 마스터 후보와 데이터 노드 역할을 동시에 수행한다면 문제가 생길 가능성이 높다.
- 또 장애 대응을 위해 특정 노드를 rolling restart 할때에도 장애 원인에 따라 마스터 노드를 재시작하거나 데이터 노드를 재시작해야 하는 상황이 다른데 이러한 fail-over 과정도 복잡해질 수 있다.
- 데이터 노드가 하나 죽은 경우라면 마스터 노드가 주 샤드가 사라진 샤드의 복제본 샤드를 새로운 주 샤드로 변경 시키고, 복제본 개수를 새로 채우는 과정을 수행하며 자연스럽게 fail-over를 할 수 있다.
- 마스터 후보 노드는 데이터 노드보다 상대적으로 성능이 많이 낮은 서버를 사용해도 무방하다.
- 데이터 노드처럼 디스크나 메모리를 많이 필요로 하지 않다.
5.2.2 마스터 후보 노드와 투표 구성원
- 클러스터가 운영되는 동안 항상 마스터 노드가 선출되어 있어야 한다. 이러한 마스터 노드를 선출하는 집단이 바로 투표 구성원이다.
- 투표 구성원은 마스터 후보 노드 중 일부 혹은 전체로 구성된 마스터 후보 노드의 부분 집합으로 마스터 선출이나 클러스터 상태 저장 등의 이사결정에 참여하는 노드의모임이다.
- 마스터 후보 노드가 클러스터에 참여하거나 떠나면 ES에서 안정성을 추가하는 방향으로 투표 구성원을 자동 조정한다.
- 이 조정 동작에는 어느정도 시간이 필요하므로, 조정이 필요한 경우 1대씩 천천히 진행하는것이 좋다.
- 동시에 절반 이상이 멈추면 클러스터는 의사결정을 내릴 수 없는 상황에 빠질 수 있다.
- 마스터 후보 노드는 홀수대를 준비하는 것이 비용 대비 효용성이 좋다.
- ES 7 버전 이상부터는 투표 구성원을 홀수로 유지하고, 후보 노드를 뺴놓는 방식으로 처리된다.
- 2K + 2대가 운영되더라도 투표 구성원은 2K + 1대만 유지하고, 1대가 죽거나 할 경우 대기중이던 1대를 투입시켜서 홀수를 유지시킨다.
5.2.3 서버 자원이 많지 않은 경우
- 적어도 3대가 확보돼야 클러스터를 구성하는 의미가 있다.
- 마스터 후보 노드 최소 3대, 데이터 노드 최소 3대가 확보돼야 기본적인 고가용성이 제공되기 떄문이다.
최소 구성, 장비 3대
- 최소의 서버 자원으로 ES 클러스터를 구성한다면 3대의 노드가 모두 마스터 후보 역할과 데이터 역할을 겸임하는 구성이 된다.
사양이 낮은 장비 4~5대가 있는 경우
- 3대는 마스터 후보 역할과 데이터 역항을 겸임하게 지정하고, 나머지 1~2대를 데이터 노드 전용으로 지정한다.
사양이 높은 장비 4~5대가 있는 경우
- 같은 비용을 지불해서 사양이 낮은 장비 3대와 사양이 높은 장비 3~4대 구성이 가능한지 확인한다.
- 변경할 수 있다면 사양이 낮은 장비 3대에 마스터 후보 역할을 주고, 사양이 높은 나머지 장비에 데이터 노드 역할을 준다.
장비 6~7대
- 마스터 후보 노드와 데이터 노드를 완전히 분리할 수 있다.
- 서비스 안정성 면에서 훨씬 이득이다.
5.2.4 서버 자원이 굉장히 많이 필요한 경우
- 한 클러스터에 동원해야 하는 물리 서버가 200대 이상인 경우 서비스 요건이 빠듯하고, 동원할 수 있는 서버 자원이 굉장히 많은 상황이 있다.
- 이런 상황에서는 먼저 용도나 중요도별로 클러스터를 더 잘게 쪼갤 수 있는지 검토해야 한다.
- ES가 선형적 확장을 잘 지원하는 구조로 설계됐다 하더라도 선출하는 마스터 노드의 수 자체를 늘릴 수는 없기 떄문에 한계가 있다.
- 클러스터를 나눌수 없다면 마스터 노드도 높은 사양의 서버로 준비하는 것이 좋다.
- 그럼에도 결국 한계가 있기 떄문에 클러스터를 쪼개고, 클러스터간 검색(cross-cluster search) 도입을 고려해보는것이 좋다.
5.2.5 사양이 크게 차이나는 서버 자원을 활용해야 하는 경우
- 가용한 서버 자원 사이의 사양 차이가 크다면 같은 운영 비용으로 성능 차이가 적은 서버로 일원화해서 교체 운영할 수 있는지 먼저 검토하자.
- 만약 그것이 어려운 상황이고 성능 차이가 좀 나더라도 남은 서버 자원을 긁어모아 활용해야 한다면 데이터 티어 구조의 도입을 고려할 수 있다.
- 성능이 높은 서버를 data_content와 data_hot 역할로, 성능이 낮은 서버를 data_warm, data_cold, data_frozen 역할로 지정한다.
- 이후 인덱스 생명 주기 관리 정책을 도입해 오래된 시계열 데이터 인덱스를 낮은 티어의 노드로 이동시키며 운영할 수 있다.
- 다만, 이때 데이터 티어 노드를 이동하는 것 역시 작업이며, 클러스터에 부하를 줄수 있으므로 상황을 잘 판단하여 신중하게 설계해야 한다.
5.2.6 조정 전용 노드
- 안정적인 클러스터 운영을 위해서는 조정 전용 노드를 두는 것이 좋다.(
node.roles: []
로 지정해 조정 역할만 수행하는 노드) - 각 데이터 노드에서 작업한 결과물을 모아서 돌려주는 작업은 생각보다 큰 부하를 줄 수 있다.
- 특히, 운영환경에서 키바나를 통해 큰 부하를 주는 경우가 발생할 수 있는데, 이떄 키바나를 조정 전용 노드만을 바라보도록 설정할 수 있다.
- 서버 자원에 여유가 있다면 읽기 작업을 담당하는 조정 전용 노드와 쓰기 작업을 담당하는 조정 전용 노드를 분리하는 것도 좋은 방법이다.
- 조정 전용 노드는 데이터 노드보다 사양이 낮은 장비로 구성해도 문제 없다.
ES7버전 이상부터 도입된 실제 메모리 서킷 브레이커가 조정 전용 노드와 궁합이 좋은데, 조정 전용 노드의 메모리 사용량이 높아지면 서킷 브레이커가 해당 요청을 차단한다.
5.2.7 한 서버에 여러 프로세스 띄우기
- 128G 이상의 메모리를 사용하는 고스펙 서버에서 32GB 정도의 힙을 설정한 ES 프로세스를 여러 개 띄우는 방법이 있는데, 이 방법으로 성능을 최대한 끌어내고자 한다면 반드시 실제와 비슷한 환경으로 테스트를 하고 방향을 결정해야 한다.
- 한 서버에서 여러 프로세스를 띄우는 방법과 유의사항을 좀 더 알아보자
유의사항
- 마스터 후보 역항을 하는 프로세스는 다중 프로세스 대상으로 고려하지 말아야 한다.(클러스터 안정성이 매우 떨어짐)
- 다중 프로세스 기동을 위해서는 cluster.name은 같게, node.name은 다르게 설정해야 하고, http, transport, path.logs, path.data같은 설정은 독립적인 설정을 가져야 한다.
- 프로세스 기동을 위해서는
cluster.routing.allocation.same_shard.host: true
설정을 지정해야 한다.(기본값 : false) - 또 OS의 file descriptor, mmap max_map_count, 네트워크 대역폭 등 자원도 공유한다는 사실과 서버에 하드웨어적인 문제가 발생하면 영향도가 N배가 될수 있다는 리스크를 염두해두어야 한다.
5.3 보안 기능 적용
- 운영환경에서는 보안이 굉장히 중요한 이슈이다.
- 기본적으로 특별한 설정을 하지 않으면 통신 암호화를 하지 않는다.
- ES나 키바나가 인터넷 환경에 노출되어 있다면 인증과 권한 부여, 분리와 관련된 기능도 중요하고, 보안 기능을 적용 해야 한다.
- 기본적으로는
xpack.security.enabled: true
설정을 바꿔주면 보안 기능을 클러스터에 적용할 수 있다.
5.3.1 모든 보안 기능을 적용하지 않은 상태
- 접근하는 사용자와 클라이언트 전수를 명확하게 제어할 수 있는 상황이라면
xpack.security.enabled: false
로 두고 운영하는 선택도 가능하다.
1
2
cluster.initial_master_nodes: ["test-es-node-01","test-es-node-02","test-es-node-03"]
xpack.security.enabled: false
5.3.2 TLS 부트스트랩 체크
- 본격적인 보안 설정을 진행하기 전에 먼저 TLS 부트스트랩 체크를 알아야 한다.
xpack.security.enabled: false
으로 구동할 경우 TLS 부트스트랩 체크를 건너뛴다.- 클러스터 기동 과정에서 노드간 transport 통신에 TLS를 적용하지 않았다면 기동을 거부한다.
- 노드간 TLS 통신을 먼저 적용해 클러스터를 기동하고, 그 이후에 내부 계정 초기화 작업을 수행해야 한다.
5.3.3 클러스터 최초 기동 시 자동 보안 설정 이용
- 자동 보안 설정 기능은 ES8 버전부터 추가된 기능이다. 8버전 미만을 사용하면 수동 설정으로 진행해야 한다.
- 전용 CA(Certificate Authority)를 생성하고, 그 CA로 서명된 인증서를 자동 발급한다.
- 노드간 transport 레이어와 REST API에 사용하는 HTTP 레이어에 TLS 통신을 적용한다.
TLS 부트스트랩 체크를 피해 최초 기동
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
node.roles: [ master, data ]
cluster.name: test-es
node.name : test-es-node01
path:
logs: /my/path/to/elasticsearch/logs
datas:
- /my/path/to/elasticsearch/data1
- /my/path/to/elasticsearch/data2
network.host: 10.0.0.1
network.bind_host: 0.0.0.0
discovery.seed_hosts: ["10.0.0.1", "10.0.0.2", "10.0.0.3"]
discovery.type: "single-node"
- 먼저 클러스터 중 한 대의 노드를 띄우고 아래 설정으로 실행한다.
- 단일 노드로 클러스터가 기동되고 나면 자동 설정이 수행되는데, 이떄 elasti usre password나 enrollment token 등이 sdtout으로 출력된다.
- 또 프로세스를 종료한 후 config 디렉토리 하위에 certs라는 디렉토리가 생겼고, 그 아래에 CA와 인증서 파일이 자동 생성됨을 확인할 수 있다.
- 이 메시지를 적당한 곳에 복사해두고, 이를 이용해서 클러스터 노드 추가, 키바나를 붙이는 작업 등을 수행할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
xapck.security.enrollment.enabled: true
xapck.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
xapck.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/http.p12
truststore.path: certs/http.p12
enrollment 토큰으로 클러스터에 노드 추가
- 단일 노드 클러스터로 띄웠던 노드의
config/elasticsearh.yml
의 discovery.type 설정을 제거해주고 다시 기동한다. - 만약 단일 노드 최초 기동시 발급했던 enrollment 토큰을 분실했다면 다음과 같이 새로운 enrollment 토큰을 발급할 수 있다.
1
bin/elastisearch-create-enrollment-token -s node
- 새롭게 투입할 노드는 아래와 같은 설정으로 기동할 수 있다.
- 이때
cluster.initial_master_nodes
,xpack.security.enabled
설정과 discovery도 기입하지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
node.roles: [ master, data ]
cluster.name: test-es
node.name : test-es-node02
path:
logs: /my/path/to/elasticsearch/logs
datas:
- /my/path/to/elasticsearch/data1
- /my/path/to/elasticsearch/data2
network.host: 10.0.0.1
network.bind_host: 0.0.0.0
- 설정 확인 후 발급한 enrollment 토큰을 지정해 노드를 기동한다.
1
bin/elasticsearch -d --enrollment-token
- 노드 기동이 완료되면 클러스터에 새 노드가 합류하고, 이후 추가된 노드의
config/certs
에도 인증서가 복사되고, 자동으로 보안 설정이 지정된것을 확인 할 수 있다.
초기 비밀번호 변경
1
2
# 합류 노드 아무곳에서나 한번 수행해서 최고 관리자 계정의 초기 비밀번호를 설정할 수 있다.
bin/elasticsearch-reest-password --interactive -u elastic
enrollment 토큰으로 키바나 기동
1
bin/elasticsearch-create-enrollment-token -s kibana
- 키바나를 기동하기 전에
config/kibana.yml
의 설정을 검토한다.
1
2
3
server.port: 5601
server.host: "10.0.0.3"
server.publicBaseUrl: "http://10.0.0.3:5601"
- enrollment를 이용한 최초 기동을 위해서는
elasticsearch.hosts
를 지정하지 않아야 한다. - 그리고 키바나를 기동하면 웹에서 enrollment 토큰을 입력하는 창이 나타나고, 여기에 토큰을 입력하면 키바나 설정이 진행된다.
- 버전(상황)에 따라 키바나에서 발급하는 추가 인증 코드를 입력하라는 안내가 나올 수 있는데 그런 경우 키바나에서 인증 코드를 발급받아 이를 키바나 웹 UI에 입력하면 초기 설정이 재개된다.
1
2
3
bin/kibana-verification-code
Your verification code is : 856 595
추가 작업
- 보안 설정을 끝낸 후에는 설정을 의도한 상황에 맞게 조금 정리해줄 필요가 있다.
- ES 노드의 c
onfig/elasticsearch.yml
을 보면discovery.seed_hosts
설정이 원하는 형태가 아닌데, 이런 부분을 마스터 후보 노드를 정확히 가리키도록 변경해야 한다. - 또
node.role
설정도 의도와 다르게 설정된 노드가 있다면 변경해주어야 한다. config/kibana.yml
의elasticsearch.hosts
설정도 원하는 리스트로 수정한다.- 최종적으로 아래와 같은 구조가 자동 구성된다.
5.3.4 키바나와 브라우저 사이에 TLS 적용
- 위 구성을 하더라도 아직 키바나와 브라우저 사이에는 TLS가 적용되지 않았다.
- 여기에는 신뢰할 수 있는 공인된 CA가 서명한 인증서를 발급받고 이를 이용해 CSR과 개인키를 생성하고 TLS를 적용하는게 필요하다.
1
bin/elasticsearch-certutil csr -name kibana-server -dns example.com,www.example.com
- 위에서 생성된 파일의 압축을 풀면
.csr
파일과.key
파일이 나오는데 이를 설정에 추가할 수 있따..csr
파일은 인증서 발급 기관으로 보내 인증서를 발급받도록 한다.- 인증서가 발급되면
kibana/config
디렉토리 하위에 파일을 위치 시키고 설정을 해주면 된다.
1
2
3
4
5
server.publicBaseUrl: "https://example.com:5601"
server.ssl.enabled: true
server.ssl.certificate: "/path/to/kibana/config/certificate.pem"
server.ssl.key: "/path/to/kibana/config/privkey/kibana-server-privkey.key"
5.3.5 수동으로 엘라스틱 서치 노드 간의 통신에 TLS 적용
- 수동으로 ES 노드간의 통신에 TLS를 적용할 수 있지만, 이 과정은 매우 길고 복잡하며 실수하기 쉽다. 따라서 일반적으로 자동 보안 설정을 이용하는 편이 낫다.
절차
- CA와 self-signed 인증서 생성
- 인증서 파일 복사
- ES 설정 변경
5.3.6 수동으로 기본 인증 설정
- ES는 계정과 역할 기반으로 인증, 권한 부여와 분리 기능을 제공한다.
- 역할에는 읽기, 쓰기, 모니터링, 스냅샷 등 ES에서 수행할 수 있는 여러 작업의 권한이 매우 세부적으로 나뉘어져 있다.
- 이 외에는 키바나에 스페이스(space)라는 개념을 통해 데이터 뷰, 비주어라이즈, 대시보드 등을 스페이스마다 독립적으로 운영할 수 있다.
최소 보안
- 노드간의 통신에 TLS를 적용하지 않았다면 ES는 애초에 기동되지 않으므로 내부 계정을 활성화시키는 단계로 진입할 수가 없다.
- 하지만 단일 노드로 구성한 개발 모드는 TLS 부트스트랩 체크를 건너뛰므로 노드간 TLS 적용 없이 기본 인증만 설정해 사용하는것이 가능하다. 기본 인증만 있는 경우 최소 보안만 설정된 상태라고 볼수 있다.
내부 계정의 초기 비밀번호 설정
1
2
3
4
5
bin/elasticsearch-reset-password --interactive -u elastic
bin/elasticsearch-reset-password --interactive -u kibana_system
# es에 자동으로 password 생성하도록 지시
bin/elasticsearch-reset-password --auto -u kibana_system
-위 비밀번호 설정을 통해 계정의 비밀번호를 얻어낸다면 이를 이용하여 ES 기본인증을 사용할 수 있다.
1
crul -H "Authorization: Basic ${accessKoten}" -XGET "http://localhost:9200?pertty=true"
키바나 설정 변경
- 키바나에서 kibana_system 계정을 사용하기 위해
config/kibana.yml
설정을 변경한다.
1
2
elasticsearch.username: "kibana_system"
elasticsearch.password:
- 계정의 비밀번호를 키바나에게 알려주기 위해
elasticsearch.password
를 설정할수도 있지만, 키스토어를 이용하는것이 안전하다.
1
2
3
bin/kibana-keystore create
bin/kibana-keystore add elasticsearch.password
- 위 설정을 추가하고 키바나를 기동하면 접속시 로그인을 요구하는 창이 등장하게 된다.
5.3.7 수동으로 REST API 호출에 TLS 적용
- 완벽히 격리된 인트라넷 안에서만 사용하는것이 아니라면 결국 transport 레이어가 아니라 HTTP 레이어에도 TLS를 적용해야 한다.
- ES의 http 레이어, 키바나에서 ES를 호출할떄 TLS 적용, 키바나와 브라우저 사이에 TLS를 수동으로 적용하는 절차를 알아보자
인증서 선택
- 기본적으로 인증서 발급, 갱신, 관리에는 비용이 들어간다.
- 노드마다 도메인이 모두 발급되어있고, 모든 클라이언트가 이 도메인을 통해 REST 요청을 한다면 이들을 묶을수 있는 와일드카드 인증서를 하나 발급받아 모든 노드에서 사용할 수 있다.
ES의 HTTP 레이어에 TLS 적용
- 예시에서는 직접 발급한 CA를 신뢰할 수 있도록 추가하고 작업한다.
bin/elasticsearch-certutil http
을 통해 인증서를 생성한다.- 생성된 zip 파일의 압축을 풀어 설정을 추가한다.
- 파일은 지정한 노드별로 생성된다.
1
2
3
4
kibana/elasticsearch-ca.pem
elasticsearch/es01/http.p12
elasticsearch/es02/http.p12
elasticsearch/es03/http.p12
- 위에 서 생성된 파일을 기준으로 다음과 같이 TLS 수동 적용을 할 수 있다.
1
2
xpack.security.http.ssl.enabled: true
[xpack.sec](xpack.security.http.ssl.keystore.path: http.p12
- 그리고 다음을 실행해서 안내에 따라 ES 키스토어에 http.p12 파일의 암호를 추가한다.
1
bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
키바나가 ES를 호출할 떄 TLS 적용
1
2
3
server.publicBaseUrl: "https://10.0.0.3:5601"
elasticsearch.hosts: ["https://10.0.0.3:9200"]
elasticsearch.ssl.certificateAuthorities: ["/path/to/kibana/config/elasticsearch-ca.pem"]
- 위 설정을 보면 elasticsearch.hosts에도 https 로 명시했는데, 이 후 키바나를 기동하면 키바나와 ES 사이에도 TLS로 통신함을 알 수 있다.
Reference
- .
Comments powered by Disqus.