brunch

You can make anything
by writing

C.S.Lewis

by 강진우 Oct 03. 2018

ElasticSearch 5.x에서 6.x로 업그레이드

ElasticSearch 

오늘 다룰 이야기는 ElasticSearch (이하 ES) 5.x에서 6.x로 버전을 업그레이드하는 방법에 대한 이야기입니다. 어떻게 하면 서비스에 큰 영향 없이 업그레이드할 수 있을지, 그리고 업그레이드 시 주의해야 할 사항들은 없는지 간단하게 살펴보겠습니다. 

본 글에서는 RPM을 통해서 설치 및 운영한다는 가정에서 진행합니다.

ES의 버전 업그레이드


ES를 업그레이드할 수 있는 방법에는 크게 두 가지가 있습니다. Full Cluster Restart와 Rolling Upgrade입니다. 단어에서 그 느낌을 알 수 있듯이 Full Cluster Restart는 전체 클러스터를 재시작하는 방법으로 다운타임이 필요하지만 클러스터의 전체 버전을 동시에 맞출 수 있기 때문에 비교적 안정적으로 작업을 할 수 있다는 장점이 있습니다. 반면이 Rolling Upgrade의 경우에는 전체 클러스터를 재시작하지 않고 노드들을 순차적으로 재시작하게 되어 다운타임이 필요하지는 않지만, 중간에 업그레이드 시에 이슈가 발생할 경우 클러스터에 문제를 일으킬 수 있다는 단점이 있습니다. (업그레이드 중간에 다른 노드가 죽거나 하는 등의 이슈 발생)

두 가지 방법은 장/단점이 확실하지만 아무래도 다운타임이 필요하지 않은 Rolling Upgrade가 더 선호되고 있습니다. 특히 메이저 버전 업그레이드가 아닌 마이너 버전 업그레이드 시에는 RPM을 업데이트해주기만 하면 될 정도로 간단하기 때문에 Rolling Upgrade가 더 많이 사용되고 있습니다.


ES 5.x에서 6.x로


그렇다면 ES 5.x 버전에서 6.x 버전으로의 업그레이드는 어떨까요? 공식 홈페이지를 보면 아래와 같이 Full Cluster Restart를 권고하는 것으로 나옵니다.

ES 6.4.1의 Upgrade 테이블

하지만 조금 더 자세히 살펴보면 5.6에서 6.x로 갈 때는 Rolling Upgrade가 가능한 것으로 나옵니다. 

그렇습니다. 5.x -> 5.6 -> 6.x로 가면 Full Cluster Restart가 아닌 Rolling Upgrade의 시나리오가 가능해집니다. 

그렇다면 구체적인 시나리오를 한 번 살펴보겠습니다.


ES 5.5.0에서 5.6.12로 업그레이드


먼저 ES 5.5.0에서 5.6.12로의 업그레이드 시나리오입니다. 

현재 운영 중인 클러스터의 버전을 5.5.0이라고 가정합니다. 

우선 이 클러스터를 5.6.12로 버전 업그레이드를 하겠습니다. 마이너 버전의 업그레이드는 매우 간단합니다. 노드의 ES 프로세스를 중지시키고 rpm 명령을 이용해서 업그레이드한 후 다시 시작시키면 됩니다.

systemctl stop elasticsearch
rpm -Uvh elasticsearch-5.6.12.rpm
systemctl start elasticsearch

정말 이렇게만 하면 됩니다. 아무런 이슈 없이 클러스터의 노드들은 5.6.12 버전으로 업그레이드가 될 것입니다.

allocation을 잠시 disable 하는 등의 추가 작업은 https://www.elastic.co/guide/en/elasticsearch/reference/current/rolling-upgrades.html 이 곳을 참고하시면 됩니다.

ES 5.6.12에서 6.4.1로 Upgrade


이제 정말 중요한 단계입니다. 5.6.12로 버전 업그레이드가 된 노드들을 기존과 마찬가지로 rpm 명령을 이용해서 업그레이드해 보겠습니다.

systemctl stop elasticsearch
rpm -Uvh elasticsearch-6.4.1.rpm
systemctl start elasticsearch

하지만 ES 프로세스가 제대로 올라오지 않는 것을 확인할 수 있을 겁니다. systemctl의 로그를 살펴보면 아래와 같은 로그를 볼 수 있습니다.

Failed at step EXEC spawning /usr/share/elasticsearch/bin/elasticsearch-systemd-pre-exec: No such file or directory
elasticsearch.service: control process exited, code=exited status=203
Failed to start Elasticsearch.
Unit elasticsearch.service entered failed state.
elasticsearch.service failed.

/usr/share/elasticsearch/bin/elasticsearch-systemd-pre-exec 파일이 없다는 메시지인데, 이 파일은 systemctl의 startup 스크립트 중에 아래와 같이 정의되어 있습니다.

... (중략) ...
User=elasticsearch
Group=elasticsearch

ExecStartPre=/usr/share/elasticsearch/bin/elasticsearch-systemd-pre-exec

ExecStart=/usr/share/elasticsearch/bin/elasticsearch \
                                                -p ${PID_DIR}/elasticsearch.pid \
                                                --quiet \
                                                -Edefault.path.logs=${LOG_DIR} \
                                                -Edefault.path.data=${DATA_DIR} \
                                                -Edefault.path.conf=${CONF_DIR}
... (중략) ...

ES 프로세스를 시작하기 전에 ExecStartPre에 정의된 실행 파일을 실행하게 되어 있는데 해당 파일이 없으니 systemctl의 startup 과정에서 실패하게 되고 ES 프로세스가 실행되지 않게 됩니다. 그럼 어떻게 해야 할까요?


startup 스크립트 교체


사실 문제의 원인을 알게 되면 기존 startup 스크립트에서 ExecStartPre 부분을 삭제하고 daemon-reload를 하면 되지 않느냐 라고 생각할 수도 있습니다. 하지만 그건 임시방편 중 하나이고 근본적인 해결책은 아닙니다. 이 문제의 근본 원인은 버전에 맞는 올바른 startup 스크립트가 없다는 것이기 때문입니다. 그럼 ES 6.4.1 버전의 startup 스크립트는 어디에 있을까요?  

/usr/lib/systemd/system/elasticsearch.service.rpmnew 

바로 이 파일이 ES 6.4.1에 맞는 올바른 startup 파일입니다. 보통 rpm 명령으로 패키지를 업그레이드하게 되면 기존 버전의 패키지에서 관리하던 파일과 충돌되는 파일들은. rpmnew라는 확장자가 붙은 파일로 변경됩니다. 그렇기 때문에 업그레이드하고 난 후 이 파일을 systemctl의 새로운 startup 파일로 지정해 주고 systemd의 스크립트를 reload 해주어야 합니다.

cp /usr/lib/systemd/system/elasticsearch.service.rpmnew /usr/lib/systemd/system/elasticsearch.service
systemctl daemon-reload

이렇게 startup 파일을 변경해 주고 다시 한번 systemctl start elasticsearch 명령을 실행하면 정상적으로 ES 프로세스가 실행되어 클러스터에 조인됨을 확인할 수 있습니다.


마치며


오늘은 ES 5.x 에서 6.x로 Full Cluster Restart가 아닌 Rolling Upgrade를 통해서 업그레이드하는 방법에 대해 이야기했습니다. 오늘 다룬 이야기를 정리하면 아래와 같습니다.

1. ES 5.x에서 5.6.x로 먼저 버전을 올립니다.
2. ES 5.6.x에서 6.x로 버전을 올립니다.
3. 버전을 올린 후. rpmnew라는 이름으로 생성된 새로운 startup 스크립트를 기본 startup 스크립트로 변경해 주고 systemd를 reload 해 줍니다.

같은 이슈로 업그레이드가 필요하신 분들은 참고하시기 바랍니다.

물론 이 외에도 ES 5.x에서 ES 6.x로 버전 업그레이드 하기 위해서는 몇가지 더 살펴봐야 할 요소들이 있습니다. (하나의 인덱스에 multi type 불가 등등..) 이런 요소들에 대해서는 다루지 않았습니다. RPM 업그레이드 시 발생할 수 있는 문제점에 대해 이야기 하고 있습니다.
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari