상세 컨텐츠

본문 제목

Windows 10에서 Docker Compose로 TLS가 적용된 Elastic Cluster 구성 - 7.16.3 버전

Data Platform/Elastic Stack

by leediz 2022. 1. 23. 17:36

본문

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를 설치하는 부분은 다른 좋은 글들이 많으니 여기선 패스하겠다.)

💡 !!작성시 오탈자 주의!!

1. 필요한 파일 준비

먼저 필요한 파일을 준비한다. 필요한 파일은 총 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
  • 폴더 내 파일 예시

2. vm.max_map_count 값 변경

Elasticsearch에서는 가상 메모리 공간을 충분히 확보해줘야 하므로 다음과 같은 설정이 필요하다. Powershell에서 다음과 같은 명령어 입력한다. 안타깝게도 영구적으로 적용되는 명령어가 아니다보니 Docker를 재실행할 때마다 실행해줘야 한다.

  • !Docker를 재실행 할때마다 실행!
> wsl -d docker-desktop
sysctl -w vm.max_map_count=262144

3. 인증서 생성을 위한 create-certs 컨테이너 실행

Elasticsearch의 노드 간 통신 시에 암호화된 통신을 한다. 따로 인증서를 생성할 수도 있지만, Elasticsearch 실행 파일 중 인증서를 만드는 파일이 있다. 온프레미스 환경에서 이를 이용해 인증서를 생성하고 TLS 설정을 적용하는 부분은 어렵고 까다로운 부분인데, Docker Compose를 사용하면 미리 설정이 적용되어 있어 이미지를 다운로드 받고 명령어를 실행해주기만 하면 된다. 방법은 다음과 같다.

  • Powershell에서 다음과 같은 명령어 입력 (create-certs.yml 파일이 있는 경로로 이동 후 실행)
> docker-compose -f create-certs.yml run --rm create_certs

4. Elastic Cluster 실행

이제 생성한 인증서를 바탕으로 암호화가 적용된 통신을 하는 Elasticsearch 컨테이너를 띄워본다.

  • Powershell에서 다음과 같은 명령어 입력
> docker-compose -f elastic-docker-tls.yml up -d

5. Password 자동생성

위와 같이 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에 해당하며 다른 계정은 이름에서 유추할 수 있듯이 각각의 목적에 따른 시스템 계정이다.

  • Powershell에서 다음과 같은 명령어 입력
> docker exec es01 /bin/bash -c "bin/elasticsearch-setup-passwords \
auto --batch --url https://es01:9200"

6. Elastic Cluster 설정 파일 수정

비밀번호를 생성했으니 설정 파일에 생성한 비밀번호를 적용해준다. 온프레미스에 설치한다면 kibana.yml파일에 수정하겠지만, Docker Compose를 사용했으므로 elastic-docker-tls.yml 파일의 kibana_system을 아래와 같이 바꿔준다. (반드시 본인의 터미널에 있는 비밀번호를 써줘야 한다.

kib01:
    ...
    environment:
      ...
      ELASTICSEARCH_USERNAME: kibana_system
      *ELASTICSEARCH_PASSWORD: PcsErW2lLTixKECMf4yZ
      ...

7. Elastic Cluster 재시작

설정 파일을 변경하였다면 변경된 설정이 적용되도록 Docker Compose를 재실행해준다. 실제로 온프레미스 환경에서도 elasticsearch.yml파일 또는 kibana.yml파일 등 설정 파일을 변경하게 되면 무조건 재실행을 해준다.

> docker-compose -f elastic-docker-tls.yml stop
> docker-compose -f elastic-docker-tls.yml up -d

8. Kibana 접속

재실행을 한 뒤 Kibana에 접속을 하려면[https://localhost:5601](https://localhost:5601) 주소로 접속을 하면 된다. 이 때 주의할 사항이 kibana와 브라우저간의 통신도 http가 아닌 https로 접속을 해야한다는 점이다. 공인된 인증서가 아닌 Elastic에서 제공한 파일을 통해 자체 인증서를 생성하여 적용했기 때문에 처음 접속하면 아래와 같이 뭔가 에러페이지 같이 생겼다. 하짐나 당황하지 않고 “고급” > “localhost(안전하지 않음)”을 차례대로 클릭하여 접속하면 된다.

접속하면 로그인페이지가 보이는데, 이때는 “elastic” 계정으로 접속하면 된다. 생성된 비밀번호 중 “elastic” 계정으로 생성된 비밀번호를 찾아서 입력한 후 접속하면 된다.

“explore on my own” 버튼을 클릭하면 아래와 같은 화면이 나온다. 이제 Elasticsearch 3대가 연결된 Kibana를 테스트하면 된다.

9. Docker Container 삭제(Volume 포함 삭제)

테스트를 다 진행한 후 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를 사용하여 쉽게 구성할 수가 있었다.

참고자료

관련글 더보기

댓글 영역