'2020/09'에 해당되는 글 6건

  1. 2020.09.23 [Elasticsearch] 멀티노드 논리적 실행.
  2. 2020.09.10 [Kibana+Docker] Docker Compose 내 elasticsearch.hosts 설정
  3. 2020.09.10 [Elasticsearch] Dynamic Templates 간단 정리
  4. 2020.09.10 [Elasticsearch+Docker] 로컬 클러스터 구성 시 흔한 실수.
  5. 2020.09.07 [Bootstrap] Nav 사용 시 Form 태그 위치 주의.
  6. 2020.09.03 [Elasticsearch] API Key (중복)

[Elasticsearch] 멀티노드 논리적 실행.

Elastic/Elasticsearch 2020. 9. 23. 16:53

elasticsearch-version.tar.gz 을 받아서 압축 해제 한 후에 단일 인스턴스에서 여러개의 노드를 실행 시켜 클러스터 구성을 하기 위한 방법 입니다.

 

Case 1)

$ ES_PATH_CONF=config bin/elasticsearch -Epath.data=data1 -Epath.logs=logs1 -d -p 1.pid

$ ES_PATH_CONF=config bin/elasticsearch -Epath.data=data2 -Epath.logs=logs2 -d -p 2.pid

$ ES_PATH_CONF=config bin/elasticsearch -Epath.data=data3 -Epath.logs=logs3 -d -p 3.pid

 

Case 2)

$ ES_PATH_CONF=config1 bin/elasticsearch -Epath.data=data1 -Epath.logs=logs1 -d -p 1.pid

$ ES_PATH_CONF=config2 bin/elasticsearch -Epath.data=data2 -Epath.logs=logs2 -d -p 2.pid

$ ES_PATH_CONF=config3 bin/elasticsearch -Epath.data=data3 -Epath.logs=logs3 -d -p 3.pid

 

별다른건 하나도 없으며, 활용하는 방법에 대한 차이 정도로 보면 될 것 같습니다.

:

[Kibana+Docker] Docker Compose 내 elasticsearch.hosts 설정

Elastic/Kibana 2020. 9. 10. 16:56

기본적으로 config/kibana.yml 에서는 array 로 설정을 하게 되어 있습니다.

Kibana : Multi-Elasticsearch 로 등록이 가능 하다는 것인데요.

 

Kibana 를 Docker 로 구성 할 경우 일반적인 yaml 문법의 array 등록 방식으로 작성을 하게 되면 에러가 발생을 합니다.

그래서 아래와 같이 작성을 하셔야 합니다.

 

[Code Example]

version: "3.7"
services:
  dockerr-kibana:
    image: docker.elastic.co/kibana/kibana:7.9.1
    container_name: docker-kibana
    environment:
      ELASTICSEARCH_HOSTS: '["http://host.docker.internal:9200","http://host.docker.internal:9201","http://host.docker.internal:9202"]'
    ports:
      - 5601:5601
    expose:
      - 5601
    restart: always
    network_mode: bridge

 

[Error Code]

version: "3.7"
services:
  dockerr-kibana:
    image: docker.elastic.co/kibana/kibana:7.9.1
    container_name: docker-kibana
    environment:
      ELASTICSEARCH_HOSTS: 
        - "http://host.docker.internal:9200"
        - "http://host.docker.internal:9201"
        - "http://host.docker.internal:9202"
    ports:
      - 5601:5601
    expose:
      - 5601
    restart: always
    network_mode: bridge

[Error Message]

$ docker-compose up
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.dockerr-kibana.environment.ELASTICSEARCH_HOSTS contains ["http://host.docker.internal:9200", "http://host.docker.internal:9201", "http://host.docker.internal:9202"], 
which is an invalid type, it should be a string, number, or a null

 

:

[Elasticsearch] Dynamic Templates 간단 정리

Elastic/Elasticsearch 2020. 9. 10. 12:18

Elasticsearch Reference 를 그대로 의역한 수준 이라고 보시면 될것 같습니다.

 

[참고문서]

www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-templates.html

www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-field-mapping.html

 

match_mapping_type)
JSON 파서를 통해서 data type 을 detection 합니다.
long, double 의 경우 integer 와 float 에 대한 정확한 detection 이 어렵기 때문에 항상 long 과 double 로 detection 하게 됩니다.

detection type 은 아래와 같습니다.
- boolean
- date
- double
- long
- object
- string

[Code Snippet from Elastic]
- long type 으로 matching 된 것을 모두 integer 로 설정 하는 것과
- string type 으로 matching 된 것을 모두 text 와 fields 설정을 이용해서 keyword 로 설정 하는 것입니다.

PUT my-index-000001
{
  "mappings": {
    "dynamic_templates": [
      {
        "integers": {
          "match_mapping_type": "long",
          "mapping": {
            "type": "integer"
          }
        }
      },
      {
        "strings": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "text",
            "fields": {
              "raw": {
                "type":  "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    ]
  }
}


match and unmatch)
이 설정은 field명에 대한 패턴 매칭을 이용해서 data type 을 detection 합니다.
unmatch 패턴은 제외 시키기 위한 설정 이라고 생각 하면 됩니다.

[Code Snippet from Elastic]
- data type 이 string 으로 매칭 된 경우 필드명을 통해 최종 설정을 하는 것입니다.
- 필드명을 통해서 data type 을 설정 하는 것입니다.

PUT my-index-000001
{
  "mappings": {
    "dynamic_templates": [
      {
        "longs_as_strings": {
          "match_mapping_type": "string",
          "match":   "long_*",
          "unmatch": "*_text",
          "mapping": {
            "type": "long"
          }
        }
      }
    ]
  }
}


match_pattern)
이 설정은 위에서 "match":   "long_*" 과 같은 wildcard 패턴을 java 정규식으로 사용하기 위한 설정입니다.

[Code Snippet from Elastic]

  "match_pattern": "regex",
  "match": "^profit_\d+$"


path_match and path_unmatch)
이 설정은 nested 나 object field 에 대한 match, unmatch 와 동일한 설정 입니다.

% Nested field type
The nested type is a specialised version of the object data type 
that allows arrays of objects to be indexed in a way 
that they can be queried independently of each other.

{name} and {dynamic_type}
이 설정은 field명을 {name} 으로 사용하고 matching 된 data type 을 {dynamic_type} 으로 사용하는 설정입니다.

[Code Snippet from Elastic]
- analyzer 로 english analyer 를 사용 하겠다는 의미 입니다. {name} == "english"
- {dynamic_type} == long 으로 매칭이 되었고 doc_values 를 사용하지 않겠다는 의미 입니다.

PUT my-index-000001
{
  "mappings": {
    "dynamic_templates": [
      {
        "named_analyzers": {
          "match_mapping_type": "string",
          "match": "*",
          "mapping": {
            "type": "text",
            "analyzer": "{name}"
          }
        }
      },
      {
        "no_doc_values": {
          "match_mapping_type":"*",
          "mapping": {
            "type": "{dynamic_type}",
            "doc_values": false
          }
        }
      }
    ]
  }
}

PUT my-index-000001/_doc/1
{
  "english": "Some English text", 
  "count":   5 
}

지금까지 보셨다면 위 설정은 Index 에 직접 설정 한다는 것을 아실 수 있습니다.

하지만 Elasticsearch 에서는 별도 Index Template 이라는 것을 제공 하고 있습니다.

 

[참고문서]

www.elastic.co/guide/en/elasticsearch/reference/7.9/index-templates.html

www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html

www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-component-template.html

 

이 index template 설정은 최신 버전으로 넘어 오면서 두 가지 타입이 존재 합니다.

- _template 에 설정

PUT /_template/<index-template>

 

- _component_template 에 설정
PUT /_component_template/<component-template>

 

이 설정이 dynamic template 과의 차이는 index 에 직접 하느냐 cluster 에 하느냐의 차이 입니다.

더불어 dynamic template 은 mapping 에 대한 내용이지만 index template 은 setting, mapping 등 모두 포함 하고 있습니다.

중요한 내용이니 꼭 인지 하시기 바랍니다.
더불어 주의 하셔야 하는 점은 이런 템플릿 설정은 인덱스가 생성 되는 시점에 적용이 되는 것이기 때문에,

이미 생성된 인덱스에는 영향을 끼치지 못한다는 것도 알아 두셔야 합니다.

 

[Code Example]

- 아래 template 과 dynamic mapping 을 함께 설정한 예제 입니다.

- 기존 예제만 함쳐 놓은 것이기 때문에 구성에 맞게 고쳐서 사용 하시면 됩니다.

PUT /_template/template_1
{
  "index_patterns" : ["te*"],
  "order" : 0,
  "settings" : {
    "number_of_shards" : 1
  },
  "mappings" : {
    "_source" : { "enabled" : false },
    "dynamic_templates": [
      {
        "integers": {
          "match_mapping_type": "long",
          "mapping": {
            "type": "integer"
          }
        }
      },
      {
        "strings": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "text",
            "fields": {
              "raw": {
                "type":  "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    ]
  }
}

 

:

[Elasticsearch+Docker] 로컬 클러스터 구성 시 흔한 실수.

Elastic/Elasticsearch 2020. 9. 10. 08:54

Elasticsearch 가 각 노드들과 discovery 를 하기 위해서는 Transport 통신이 이루어져야 합니다.

문서에 정확하게 나와 있으나 놓치기 쉬운 부분이라 기록해 봅니다.

 

[참고문서]

https://www.elastic.co/guide/en/elasticsearch/reference/current/discovery-settings.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery-bootstrap-cluster.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery-settings.html

 

[Content Snippet]

[discovery.seed_hosts]

Provides a list of the addresses of the master-eligible nodes in the cluster.

1. transport.profiles.default.port
2. transport.port
If neither of these is set then the default port is 9300.

[Example Configuration]

[Node 1 - docker-compose.yml]
version: '3.7'

services:
  docker-es:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.9.1
    container_name: e1
    environment:
      - cluster.name=e3k1
      - node.name=e1
...중략...
      - discovery.seed_hosts=host.docker.internal:9300,host.docker.internal:9301,host.docker.internal:9302
      - cluster.initial_master_nodes=e1,e2,e3
...중략...

[Node 2 - docker-compose.yml]
version: '3.7'

services:
  docker-es:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.9.1
    container_name: e2
    environment:
      - cluster.name=e3k1
      - node.name=e2
...중략...
      - discovery.seed_hosts=host.docker.internal:9300,host.docker.internal:9301,host.docker.internal:9302
      - cluster.initial_master_nodes=e1,e2,e3
...중략...

[Node 3 - docker-compose.yml]
version: '3.7'

services:
  docker-es:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.9.1
    container_name: e3
    environment:
      - cluster.name=e3k1
      - node.name=e3
...중략...
      - discovery.seed_hosts=host.docker.internal:9300,host.docker.internal:9301,host.docker.internal:9302
      - cluster.initial_master_nodes=e1,e2,e3
...중략...

 

위에 작성된 설정 예제는 로컬에서 3개의 Elasticsearch 컨테이너를 실행 시켜서 클러스터링 시키는 예제 입니다.

이 방법 말고도 하나의 docker-compose.yml 에 구성을 하셔도 됩니다. (단, 설정이 조금 달라 집니다.)

 

주의 점은,

위에 언급된 내용처럼 Transport 통신을 한다는 것을 잊으면 안된다는 것입니다.

:

[Bootstrap] Nav 사용 시 Form 태그 위치 주의.

ITWeb/개발일반 2020. 9. 7. 12:21

기억하기 위해 기록 합니다.

 

[참고문서]

bootstrap ui nav document

 

정상 동작 코드)

<nav>
  <div class="nav nav-tabs nav-pills" id="nav-tab" role="tablist">
    <a class="nav-item nav-link active" id="nav-terraform-configuration" data-toggle="tab" href="#terraform-configuration" role="tab" aria-controls="terraform-configuration" aria-selected="true">Step 1 - Terraform</a>
...중략...    
  </div>
</nav>

<div class="tab-content" id="nav-tabContent">
  
  <div class="tab-pane fade show active" id="terraform-configuration" role="tabpanel" aria-labelledby="nav-terraform-configuration">
    <form name="terraformForm">
...중략...
		</form>
	</div>

	<div class="tab-pane fade" id="kibana-installation" role="tabpanel" aria-labelledby="nav-kibana-installation">
...중략...
	</div>
</div>

 

비정상 동작 코드)

<nav>
  <div class="nav nav-tabs nav-pills" id="nav-tab" role="tablist">
    <a class="nav-item nav-link active" id="nav-terraform-configuration" data-toggle="tab" href="#terraform-configuration" role="tab" aria-controls="terraform-configuration" aria-selected="true">Step 1 - Terraform</a>
...중략...    
  </div>
</nav>

<div class="tab-content" id="nav-tabContent">
	
	<form name="terraformForm">
  <div class="tab-pane fade show active" id="terraform-configuration" role="tabpanel" aria-labelledby="nav-terraform-configuration">
...중략...
	</div>
	</form>

	<div class="tab-pane fade" id="kibana-installation" role="tabpanel" aria-labelledby="nav-kibana-installation">
...중략...
	</div>
</div>

위 코드의 차이점은 <form> 태그의 위치 입니다.

 

정상적으로 동작 하는 코드에서는

- <div> tab-content 내부에 tab 영역에 해당 하는 <div> 안쪽에 선언이 되어 있고,

- 비정상적으로 동작하는 코드에서는 밖에 선언이 되어 있습니다.

 

:

[Elasticsearch] API Key (중복)

Elastic/Elasticsearch 2020. 9. 3. 10:16

이전에 작성한 글과 중복 내용이 있습니다.

 

이전 글)

jjeong.tistory.com/1487

 

Elasticsearch + Kibana 사용 시 basic security 설정을 enable 하게 되면 Restful API 사용을 위한 API Key 를 생성 해서 사용을 해야 합니다.

 

Kibana devtools 를 이용해서 할 경우 인증이 되어 있어서 /_security/api_key 사용이 가능 하지만 Postman 과 같은 걸 이용할 경우 id:pwd 를 넣어 줘야 합니다.

[Case 1]
http://elastic:elasticpassword@localhost:9200/_security/api_key

[Case 2]
curl -XPUT -u elastic:elasticpassword "http://localhost:9200/_security/api_key" -d
{
  "name": "team-index-command",
  "expiration": "10m", 
  "role_descriptors": { 
    "role-team-index-command": {
      "cluster": ["all"],
      "index": [
        {
          "names": ["*"],
          "privileges": ["all"]
        }
      ]
    }
  }
}

 

API Key 구조)

- /_security/api_key 를 이용해서 생성을 하면 아래와 같은 값이 나옵니다.

[Request]
POST /_security/api_key
{
  "name": "team-index-command",
  "expiration": "10m", 
  "role_descriptors": { 
    "role-team-index-command": {
      "cluster": ["all"],
      "index": [
        {
          "names": ["*"],
          "privileges": ["all"]
        }
      ]
    }
  }
}

[Response]
{
  "id" : "87cuynIBjKAXtnkobGgo",
  "name" : "team-index-command",
  "expiration" : 1592529999478,
  "api_key" : "OlVGT_Q8RGq1C_ASHW7pGg"
}

- API Key 는 id:api_key 조합으로 base64 encoding 된 값입니다.

base64_encode("87cuynIBjKAXtnkobGgo"+":"+"OlVGT_Q8RGq1C_ASHW7pGg")

 

API Key 를 이용한 Restful API 호출)

$ curl 
  -H "Authorization: ApiKey VGVVOXluSUJHUUdMaHpvcUxDVWo6aUtfSmlEMmdSMy1FUUFpdENCYzF1QQ==" 
  http://localhost:9200/_cluster/health

 

: