Windows 10에서 Docker Compose로 TLS가 적용된 Elastic Cluster 구성 - 7.16.3 버전
Single Node로 Elasticsearch와 Kibana를 설치하여 테스트할 수도 있지만, 테스트가 아닌 운영환경에서는 단 3개의 노드라도 Cluster를 구성해서 사용하게된다. 개인적으로 테스트를 위해 Cluster구성을 하려면 물리적인 서버부터 제약이 생긴다. VirtualBox나 VMWare를 설치하여 Cluster구성을 할 수도 있지만 OS Setting부터 번거로운일이 굉장히 많다. 다행히 Docker Compose를 이용하여 Elastic Cluster를 구성하는 예제가 Elastic 공식문서에 있다. 이번 포스팅에서는 Windows10 환경에서 TLS까지 적용된 Elasticsearch Cluster 3대와 Kibana 서버 1대를 Docker Compose로 띄어보는 예제를 따라해보고자 한다. 참고페이지는 여기이다. (Docker를 설치하는 부분은 다른 좋은 글들이 많으니 여기선 패스하겠다.)
먼저 필요한 파일을 준비한다. 필요한 파일은 총 4개로 각각의 파일 내용은 다음과 같다.
instances.yml 파일
instances:
- name: es01
dns:
- es01
- localhost
ip:
- 127.0.0.1
- name: es02
dns:
- es02
- localhost
ip:
- 127.0.0.1
- name: es03
dns:
- es03
- localhost
ip:
- 127.0.0.1
- name: 'kib01'
dns:
- kib01
- localhost
.env 파일
COMPOSE_PROJECT_NAME=es
CERTS_DIR=/usr/share/elasticsearch/config/certificates
VERSION=7.16.3
create-certs.yml 파일
version: '2.2'
services:
create_certs:
image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
container_name: create_certs
command: >
bash -c '
yum install -y -q -e 0 unzip;
if [[ ! -f /certs/bundle.zip ]]; then
bin/elasticsearch-certutil cert --silent --pem --in config/certificates/instances.yml -out /certs/bundle.zip;
unzip /certs/bundle.zip -d /certs;
fi;
chown -R 1000:0 /certs
'
working_dir: /usr/share/elasticsearch
volumes:
- certs:/certs
- .:/usr/share/elasticsearch/config/certificates
networks:
- elastic
volumes:
certs:
driver: local
networks:
elastic:
driver: bridge
elastic-docker-tls.yml 파일
version: '2.2'
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
container_name: es01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es02,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.license.self_generated.type=trial
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=true
- xpack.security.http.ssl.key=$CERTS_DIR/es01/es01.key
- xpack.security.http.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
- xpack.security.http.ssl.certificate=$CERTS_DIR/es01/es01.crt
- xpack.security.transport.ssl.enabled=true
- xpack.security.transport.ssl.verification_mode=certificate
- xpack.security.transport.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
- xpack.security.transport.ssl.certificate=$CERTS_DIR/es01/es01.crt
- xpack.security.transport.ssl.key=$CERTS_DIR/es01/es01.key
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data01:/usr/share/elasticsearch/data
- certs:$CERTS_DIR
ports:
- 9200:9200
networks:
- elastic
healthcheck:
test: curl --cacert $CERTS_DIR/ca/ca.crt -s https://localhost:9200 >/dev/null; if [[ $$? == 52 ]]; then echo 0; else echo 1; fi
interval: 30s
timeout: 10s
retries: 5
es02:
image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
container_name: es02
environment:
- node.name=es02
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.license.self_generated.type=trial
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=true
- xpack.security.http.ssl.key=$CERTS_DIR/es02/es02.key
- xpack.security.http.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
- xpack.security.http.ssl.certificate=$CERTS_DIR/es02/es02.crt
- xpack.security.transport.ssl.enabled=true
- xpack.security.transport.ssl.verification_mode=certificate
- xpack.security.transport.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
- xpack.security.transport.ssl.certificate=$CERTS_DIR/es02/es02.crt
- xpack.security.transport.ssl.key=$CERTS_DIR/es02/es02.key
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data02:/usr/share/elasticsearch/data
- certs:$CERTS_DIR
networks:
- elastic
es03:
image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
container_name: es03
environment:
- node.name=es03
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es02
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.license.self_generated.type=trial
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=true
- xpack.security.http.ssl.key=$CERTS_DIR/es03/es03.key
- xpack.security.http.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
- xpack.security.http.ssl.certificate=$CERTS_DIR/es03/es03.crt
- xpack.security.transport.ssl.enabled=true
- xpack.security.transport.ssl.verification_mode=certificate
- xpack.security.transport.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
- xpack.security.transport.ssl.certificate=$CERTS_DIR/es03/es03.crt
- xpack.security.transport.ssl.key=$CERTS_DIR/es03/es03.key
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data03:/usr/share/elasticsearch/data
- certs:$CERTS_DIR
networks:
- elastic
kib01:
image: docker.elastic.co/kibana/kibana:${VERSION}
container_name: kib01
depends_on: {"es01": {"condition": "service_healthy"}}
ports:
- 5601:5601
environment:
SERVERNAME: localhost
ELASTICSEARCH_URL: https://es01:9200
ELASTICSEARCH_HOSTS: https://es01:9200
ELASTICSEARCH_USERNAME: kibana_system
ELASTICSEARCH_PASSWORD: CHANGEME
ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES: $CERTS_DIR/ca/ca.crt
SERVER_SSL_ENABLED: "true"
SERVER_SSL_KEY: $CERTS_DIR/kib01/kib01.key
SERVER_SSL_CERTIFICATE: $CERTS_DIR/kib01/kib01.crt
volumes:
- certs:$CERTS_DIR
networks:
- elastic
volumes:
data01:
driver: local
data02:
driver: local
data03:
driver: local
certs:
driver: local
networks:
elastic:
driver: bridge
폴더 내 파일 예시
Elasticsearch에서는 가상 메모리 공간을 충분히 확보해줘야 하므로 다음과 같은 설정이 필요하다. Powershell에서 다음과 같은 명령어 입력한다. 안타깝게도 영구적으로 적용되는 명령어가 아니다보니 Docker를 재실행할 때마다 실행해줘야 한다.
> wsl -d docker-desktop
sysctl -w vm.max_map_count=262144
Elasticsearch의 노드 간 통신 시에 암호화된 통신을 한다. 따로 인증서를 생성할 수도 있지만, Elasticsearch 실행 파일 중 인증서를 만드는 파일이 있다. 온프레미스 환경에서 이를 이용해 인증서를 생성하고 TLS 설정을 적용하는 부분은 어렵고 까다로운 부분인데, Docker Compose를 사용하면 미리 설정이 적용되어 있어 이미지를 다운로드 받고 명령어를 실행해주기만 하면 된다. 방법은 다음과 같다.
> docker-compose -f create-certs.yml run --rm create_certs
이제 생성한 인증서를 바탕으로 암호화가 적용된 통신을 하는 Elasticsearch 컨테이너를 띄워본다.
> docker-compose -f elastic-docker-tls.yml up -d
위와 같이 Powershell에 별다른 에러 없이 끝났다면 Elastic Cluster가 잘 생성되었다는 뜻이다. 이제 TLS가 적용된 Elasticsearch 노드 3대와 Kibana 노드 1대가 실행중이다. 하지만 Elasticsearch를 제대로 잘 사용하려면 Elasticsearch 필수 계정의 암호를 생성해줘야 한다. 대게는 계정을 생성하며 비밀번호를 직접 지정해주지만, 이번 케이스에서는 편의를 위해 계정별로 자동으로 암호를 생성하게 한다. 참고로 필수 계정은 elastic, kibana, kibana_system, logstash_system, beats_system, apm_system, remote_monitoring_user 가 있다. 이 중 elastic은 super user에 해당하며 다른 계정은 이름에서 유추할 수 있듯이 각각의 목적에 따른 시스템 계정이다.
> docker exec es01 /bin/bash -c "bin/elasticsearch-setup-passwords \
auto --batch --url https://es01:9200"
비밀번호를 생성했으니 설정 파일에 생성한 비밀번호를 적용해준다. 온프레미스에 설치한다면 kibana.yml파일에 수정하겠지만, Docker Compose를 사용했으므로 elastic-docker-tls.yml 파일의 kibana_system을 아래와 같이 바꿔준다. (반드시 본인의 터미널에 있는 비밀번호를 써줘야 한다.
kib01:
...
environment:
...
ELASTICSEARCH_USERNAME: kibana_system
*ELASTICSEARCH_PASSWORD: PcsErW2lLTixKECMf4yZ
...
설정 파일을 변경하였다면 변경된 설정이 적용되도록 Docker Compose를 재실행해준다. 실제로 온프레미스 환경에서도 elasticsearch.yml파일 또는 kibana.yml파일 등 설정 파일을 변경하게 되면 무조건 재실행을 해준다.
> docker-compose -f elastic-docker-tls.yml stop
> docker-compose -f elastic-docker-tls.yml up -d
재실행을 한 뒤 Kibana에 접속을 하려면[https://localhost:5601](https://localhost:5601)
주소로 접속을 하면 된다. 이 때 주의할 사항이 kibana와 브라우저간의 통신도 http
가 아닌 https
로 접속을 해야한다는 점이다. 공인된 인증서가 아닌 Elastic에서 제공한 파일을 통해 자체 인증서를 생성하여 적용했기 때문에 처음 접속하면 아래와 같이 뭔가 에러페이지 같이 생겼다. 하짐나 당황하지 않고 “고급” > “localhost(안전하지 않음)”을 차례대로 클릭하여 접속하면 된다.
접속하면 로그인페이지가 보이는데, 이때는 “elastic” 계정으로 접속하면 된다. 생성된 비밀번호 중 “elastic” 계정으로 생성된 비밀번호를 찾아서 입력한 후 접속하면 된다.
“explore on my own” 버튼을 클릭하면 아래와 같은 화면이 나온다. 이제 Elasticsearch 3대가 연결된 Kibana를 테스트하면 된다.
테스트를 다 진행한 후 Volume, Network를 포함한 Elasticsearch Cluster Container 전체를 삭제하고 싶다면 아래와 같은 명령어로 삭제하면 된다. 이 때 모든 데이터 삭제되므로 중요한 데이터가 있다면 백업한 후 삭제할 것을 추천한다.
> docker-compose -f elastic-docker-tls.yml down -v
이번 포스팅에서는 Windows 10 환경에서 Docker Compose를 이용하여 TLS가 적용된 Elastic Cluster 구성을 실습해보았다. 온프레미스 환경에서 Elastic Cluster를 구성하는것 만으로도 어려울수가 있는데, 더 어렵고 까다로운 TLS를 적용하려면 삽질을 많이 해야 했을 것이다. 단순 기능 테스트를 위해서라면 이렇게 Docker Compose를 사용하여 쉽게 구성할 수가 있었다.
[Elastic Stack] Filebeat multiple output 에러 (0) | 2022.03.16 |
---|---|
[Elastic Stack] Elasticsearch Index와 Shard 개념 (0) | 2022.03.03 |
[Elastic Stack] Elasticsearch 주요 용어 (0) | 2022.02.24 |
[Elastic Stack] Elasticsearch 특징 (0) | 2022.02.10 |
Elastic Stack 이란? (0) | 2022.01.24 |
댓글 영역