top bar

글 목록

레이블이 docker-compose인 게시물을 표시합니다. 모든 게시물 표시
레이블이 docker-compose인 게시물을 표시합니다. 모든 게시물 표시

2017년 7월 28일 금요일

[Elasticsearch] 'Docker Compose' 로 ELK 스택 구성


 이번엔 Docker를 이용해 ELK 스택을 구성해 보겠다. Docker는 LXC 기술중 하나로서, 이식성이 뛰어난 격리된 프로세스 컨테이너를 통해 어플리케이션을 구동하는 방식이다. Docker 관련 문서들은 차고 넘치니, 따로 정리하지는 않겠다.

Docker Compose는 이러한 Docker 컨테이너 여러개를 조합(Compose)하여 설정 할 수 있게 해주고, 따라서 다수의 컨테이너 설정을 하나의 파일에서 가능하게 해 준다. 또한 설정된 컨테이너를 한번에, 또는 각각 하나씩 구동 할 수도 있다.

하지만 단 하나의 컨테이너를 구동할때도 Docker Compose가 유용하다.
가령, 아래의 tomcat 컨테이너를 띄우는 Docker 명령이 있다고 하자.

$ docker run -it --rm -p 8888:8080 tomcat:8.0

 위의 설정과 동일한 컨테이너를 Docker Compose로는 아래와 같이 설정하여 구동할 수 있다.

version: '2'
services:
  tomcat:
    image: tomcat:8.0
    ports:
      - 8888:8080

뭔가 텍스트가 더 많이 들어 간 것 같지만 기분 탓일 거다. 일단 깔끔하게 YAML 형식을 지원하는 Docker Compose 설정이 보기가(가독성이) 더 좋아 보인다. 위의 기본 docker 명령 예제에서 입력한 옵션은 많지 않지만, 훨씬 더 복잡한 옵션을 입력하고 컨테이너를 구동한다고 했을때 옵션을 입력하기도, 확인하기도 어려울 것이다. 따라서, 복잡한 하나 또는 여러개의 컨테이너 설정, 그리고 그 컨테이너들간의 관계를 설정 해야할 때는 당연히 뒤도 안보고 Docker Compose를 사용해야 한다.



docker-compose.yml 작성



ELK를 위한 docker-compose.yml 파일의 기본 골격은 아래와 같다.

version: '2'
services:
 elasticsearch:
  .
  .
  .

 logstash:
  .
  .
  .

 kibana:
  .
  .
  .

하나씩 살펴보자.

1) Elasticsearch
elasticsearch:
  image: docker.elastic.co/elasticsearch/elasticsearch:5.4.0
  container_name: elasticsearch
  volumes:
   - ./elasticsearch/config/elasticsearch.yml:/usr/share
/elasticsearch/config/elasticsearch.yml
   - ./elasticsearch/data:/usr/share/elasticsearch/data
  environment:
   ES_JAVA_OPTS: "-Xmx2048m -Xms2048m"
  ports:
   - 9200:9200
   - 9300:9300

'volumes' 설정을 통해서 외부의 파일시스템과 컨테이너 내부의 파일시스템을 마운트한다. [외부디렉토리]: [내부디렉토리] 와 같은 형식으로 마운트할 수 있는데, 위에서 보는것과 같이 파일 자체(elasticsearch.yml)도 마운트 가능하다.

'environment'로 elasticsearch 인스턴스의 JVM 옵션을 줄 수 있다. 'ports' 또한 컨테이너 외/내부의 포트를 설정하여 해당 포트를 통한 통신을 가능하게 해 준다. 별거 없다. ㅇㅇ

2) Logstash
 logstash:
  image: docker.elastic.co/logstash/logstash:5.4.0
  container_name: logstash
  command: logstash -f /usr/share/logstash/pipeline/logstash.conf
  volumes:
   - ./logstash/config/:/usr/share/logstash/config/
   - ./logstash/pipeline/:/usr/share/logstash/pipeline/
  environment:
   LS_JAVA_OPTS: "-Xmx2048m -Xms2048m"
  ports:
   - 10080:10080
  depends_on:
   - elasticsearch

elasticsearch 설정과 흡사하다. 단, 'command' 설정으로 컨테이너를 구동할때 'logstash -f ... ' 명령어로 logstash 를 실행하도록 한다. 물론 '-f' 옵션 다음의 오는 경로는 컨테이너 내부 파일 경로이다.

'depends_on' 은 'elasticsearch' 컨테이너가 시작한 후에 logstash 컨테이너를 구동하도록 하는 설정이다.

3) Kibana
 kibana:
  image: docker.elastic.co/kibana/kibana:5.4.0
  container_name: kibana
  volumes:
   - ./kibana/config/:/usr/share/kibana/config
  ports:
   - 5601:5601
  depends_on:
   - logstash

설명할 건 다 했으니 생략.



docker-compose 구동



'docker-compose.yml' 파일이 위치하고 있는 디렉토리에서,
아래와 같은 명령을 통해 구동 한다.

$ docker-compose up -d

로그를 보고 싶다면 아래 명령어를 사용한다.

$ docker-compose logs -f --tail="100" [service_name]

설정파일의 전체 내용은 아래에 있다.

https://gist.github.com/JuPyoHong/17362d9e0b64256b627dc063b00cc357


2017년 5월 10일 수요일

[Elasticsearch] AWS + Docker 기반 Elasticsearch 클러스터 구성

회사 업무 관계로, AWS + Docker 기반의 Elasticsearch 클러스터를 구성하게 되었다. 그냥 지나가면 까먹을 것 같아 정리 한다.

00. Prerequisite



docker : Docker version 1.13.0
docker-compose : docker-compose version 1.10.0
AWS instance Type : r4.large
Elasticsearch : 5.4.0

먼저 작업 디렉토리를 ~/elasticsearch 라고 가정하자.


01. Dockerfile 작성



아래와 같이 Dockerfile 을 작성한다.

FROM docker.elastic.co/elasticsearch/elasticsearch:5.4.0
 
WORKDIR /usr/share/elasticsearch
RUN bin/elasticsearch-plugin install discovery-ec2

베이스 이미지는 'docker.elastic.co/elasticsearch/elasticsearch:5.4.0' 이다.

AWS EC2 인스턴스를 사용해 클러스터를 구성해야 하기 때문에 기존의 zen discovery 는 사용할 수 없다. 따라서 docker 이미지를 구울때 'discovery-ec2' 플러그인을 설치해야 한다.


02. docker build



Dockerfile이 위치하고 있는 디렉토리에서, 아래와 같이 'elasticsearch-aws' 라는 이름으로
docker 이미지를 생성한다.

$ docker build -t elasticsearch-aws .

> build log
Sending build context to Docker daemon 4.096 kB
Step 1/4 : FROM docker.elastic.co/elasticsearch/elasticsearch:5.4.0
 ---> 4c093701c312
Step 2/4 : WORKDIR /usr/share/elasticsearch
 ---> c784b97dc1e0
Removing intermediate container a93494f1f6f3
Step 3/4 : RUN bin/elasticsearch-plugin install discovery-ec2
 ---> Running in a609bd73f8c7
-> Downloading discovery-ec2 from elastic
[=================================================] 100%??
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@     WARNING: plugin requires additional permissions     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* java.lang.RuntimePermission accessDeclaredMembers
* java.lang.RuntimePermission getClassLoader
See http://docs.oracle.com/javase/8/docs/technotes/guides/security
/permissions.html
for descriptions of what these permissions allow and 
the associated risks.
-> Installed discovery-ec2
 ---> 6108494a5131
Removing intermediate container a609bd73f8c7
Step 4/4 : EXPOSE 9200 9300
 ---> Running in 78105875f3c7
 ---> e6fd47d7d666
Removing intermediate container 78105875f3c7
Successfully built e6fd47d7d666

위의 Warning은 일단 무시하자.


03. elasticsearch.yml 작성



작업 디렉토리에 'config' 디렉토리를 생성하고,
elasticsearch YAML 설정파일을 작성하여 위치 시키자.

cluster.name: my-aws-cluster
 
node.name: my-node2
 
node.master: true
node.data: true
 
network.host: 0.0.0.0
network.publish_host: _ec2:privateIp_
 
discovery.type: ec2
 
discovery.zen.minimum_master_nodes: 1
discovery.zen.ping.unicast.hosts:
 - [this host ip]
 - [host ip 1]
 - [host ip 2]
 
xpack.security.enabled: false

위와 같이 'network.publish_host' 설정을 하게되면 ec2의 private ip 로 호스트가 바인딩 된다. 'discovery.type: ec2' 설정도 빠지면 안된다.


04. docker-compose.yml 작성



그냥 docker run 명령어로 필요한 옵션을 주어 동작을 하게 할 순 있지만, 옵션을 부여하는게 불편하고, 스크립트로 작성해도 유지보수가 귀찮다.

따라서 YAML 형식의 설정을 지원하는 docker-compose로 컨테이너를 구동하려고 한다.
아래와 같이 작업 디렉토리에 docker-compose.yml 파일을 작성한다.

version: '2'
services:
 elasticsearch:
  image: elasticsearch-aws
  container_name: elasticsearch
  volumes:
   - ./config/elasticsearch.yml:/usr/share/elasticsearch/config
/elasticsearch.yml
   - esdata:/usr/share/elasticsearch/data
  ports:
   - 9200:9200
   - 9300:9300
  environment:
   ES_JAVA_OPTS: "-Xmx2048m -Xms2048m"
 
volumes:
 esdata:
  driver: local


위에서 중요한 설정은 'volumes' 인데, 일단 해당 설정의 첫번째 라인은, 호스트 서버의 외부 elasticsearch.yml 파일을 컨테이너 내부의 elasticsearch.yml 파일에 덮어 쓰는 것이다.
그리고 두번째 라인은 'named volume' 으로서, 컨테이너 내부 디렉토리에 컨테이너 외부 디렉토리를 마운트시키는데, docker자체에서 'esdata' 라는 볼륨으로 관리된다.

해당 볼륨은 service의 이름과 합쳐져서 'elasticsearch_esdata' 라는 볼륨으로 생성되며,
아래와 같은 명령어로 확인 할 수 있다.

$ docker volume inspect elasticsearch_esdata
[
    {
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/elasticsearch_esdata/_data",
        "Name": "elasticsearch_esdata",
        "Options": {},
        "Scope": "local"
    }
]

위에 'Mountpoint' 값이 마운트된 컨테이너 외부 호스트 디렉토리를 가르킨다.


05. 구동



아래의 명령어로 구동시킨다. 백그라운드 구동일 경우 '-d' 옵션을 붙인다.

$ docker-compose up


06. 클러스터링



위의 01~04 단계를 거친 동일한 docker 기반 elasticsearch 설정을 가지고,
2대의 AWS 인스턴스에 elasticsearch 노드를 띄워서 클러스터링을 해 보려고 한다.
아래를 순서대로 진행한다.

① 1번 AWS 인스턴스에 'node1' elasticsearch 노드 구동
② 2번 AWS 인스턴스에 'node2' elasticsearch 노드 구동

① ② 를 차례대로 진행하면 node1 쪽 로그에 아래와 같이 출력된다.






로그를 보면 알겠지만 뒤늦게 구동된 node2 가 마스터노드인 node1을 발견했다는 내용을 확인 할 수 있다.

그리고 동시에 node2 쪽 로그에는 아래와 같이 출력된다.





반대로 마스터노드인 node1에서는 node2를 ec2 discovery를 이용해 찾고, 클러스터에 추가했다는 내용을 확인 할 수 있다.

이로서 클러스터 구축 완료!