반응형

준비 작업:  Elastic 8.0 및 Kibana 설치하기

아래 김종민 님의 설명을 읽고, ElasticsearchKibana 설치하는 것이 제일 쉽고 간단하다.

 

 

Elastic 8.0 설치하기 - Jongmin's Lifelog

정말 오랬만에 블로그 포스팅을 하네요. 얼마 전에 드디어 Elastic 8.0 이 출시되었습니다. 6.x 릴리스 까지는 보통 1년 ~ 18개월 정도의 텀을 두고 비교적 빠르게 버전 업데이트를 했는데 7.x 릴리스

kimjmin.net

 

##
## Elasticsearch 기동하기
##

$  bin/elasticsearch


##
## Kibana 기동하기
##   주의: 명령 옵션으로 --host를 지정하지 않으면, 기본값이 127.0.0.1로 설정된다.
##        만약 Web Browser가 kibana 서버와 다른 곳에 있다면 반드시 아래와 같이 
##        외부에서 접근 가능한 서버 주소를 지정해주어야 한다.

$ bin/kibana  --host=192.168.0.11

 

 


 

Elasticsearch 서버와 Kibana 서버를 설치했으면, 아래의 문서를 보면서 Python Example App을 작성한다.

 

Elasticsearch Python Client Example

2022년 11월 현재, 아래의 Web Docs가 가장 쉽게 설명된 것 같다.

Python PKG 설치, 인증/연결, 설정, Client Example Code 등 필요한 내용을 다 포함하고 있다.

 

 

Elasticsearch Python Client [8.5] | Elastic

 

www.elastic.co

 

 

아래  Docs는 초반에 "Elastic Cloud"를 먼저 예시로 설명하고 있는데,
만약 Private 환경(즉, self-managed cluster)에서 Client Example을 테스트할 것이라면
이 Docs의 아래 부분만 읽으면 된다.

[ 즉, 바로 이 부분부터 읽고 따라하면 된다 ]
https://www.elastic.co/guide/en/elasticsearch/client/python-api/master/connecting.html#connect-self-managed-new

 

 

Connecting | Elasticsearch Python Client [master] | Elastic

The async client shouldn’t be used within Function-as-a-Service as a new event loop must be started for each invocation. Instead the synchronous Elasticsearch client is recommended.

www.elastic.co

 

CRUD(Create, Read, Update, Delete) 예제를 보고 싶다면, 아래  Web Docs를 열람.

 

https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/examples.html

 

Examples | Elasticsearch Python Client [8.5] | Elastic

Below you can find examples of how to use the most frequently called APIs with the Python client. Indexing a documentedit To index a document, you need to specify three pieces of information: index, id, and a body: from datetime import datetime from elasti

www.elastic.co

 

 

실제로 위 Web Docs를 보고 조금 변경해서 작성해본 예시이다.

그냥 Copy & Paste해서  `python3  myexample.py` 명령을 수행하면 된다.

 

Document 1개를 Elasticsearch에 저장하는 예제

from datetime import datetime
from elasticsearch import Elasticsearch

##
## NOTE : Configuration for multi node
##
NODES = [ "https://10.1.3.166:9200" ]

##
## Password for the 'elastic' user generated by Elasticsearch
##
ELASTIC_PASSWORD = "mypasswd"

##
## Create the client instance
##
es = Elasticsearch(
    NODES,
    ca_certs="/MyWorkSpace/elastic-stack-metal-install/elasticsearch-8.5.1/config/certs/http_ca.crt",
    basic_auth=("elastic", ELASTIC_PASSWORD)
)

## Create documents
doc = {
    'my-key-example-a': 'my-value-1',
    'my-key-example-b': 'my-value-2',
    'date': datetime.now(),
    'msg': "my log message example... hello~  world ^^",
}

resp = es.index(index="example-index-0", id=0, document=doc)
print(resp['result'])

 

Bulk로 많은 Document를 Elasticsearch에 저장하는 예제

from datetime import datetime
from elasticsearch import Elasticsearch
from randmac import RandMac


NODES = [ "https://10.1.3.166:9200" ]

##
## Password for the 'elastic' user generated by Elasticsearch
##
ELASTIC_PASSWORD = "mypasswd"

##
## Create the client instance
##
es = Elasticsearch(
    NODES,
    ca_certs="/MyWorkSpace/elastic-stack-metal-install/elasticsearch-8.5.1/config/certs/http_ca.crt",
    basic_auth=("elastic", ELASTIC_PASSWORD)
)

doc_id = 0
loop_cnt = 0

##
## Create documents
##
##   참고: 아래 for 문은 document 예시를 그럴듯하게 만들기 위함이다.
##        실제 Elasticsearch와는 아무런 관련이 없다. ^^
ip_networks = ["10", "172", "192"]

for ii in ip_networks:
    for xx in range(254):
        for yy in range(254):
            for zz in range(254):
                macaddress = str(RandMac())
                doc = {
                    'app': 'nac-server',
                    'level': 'info',
                    'date': datetime.now(),
                    'ip-address': ii + '.' + str(xx) + '.' +  str(yy) + '.' + str(zz),
                    'mac-address': macaddress,
                    'msg': 'Device ' + macaddress + ' is started',
                }

                doc_id += 1
                loop_cnt += 1
                resp = es.index(index="example-index-0", id=doc_id, document=doc)
            print("Count: " + str(loop_cnt) + "   " + str(resp['_index']) + "   " + str(resp['_id']) + "   " + str(resp['result']) + "   shard:" + str(resp['_shards']) + "   " + str(resp['_seq_no']))

print("\nTotal Document: " + str(doc_id))

 

Document를 조회하기

from datetime import datetime
from elasticsearch import Elasticsearch

NODES = [ "https://10.1.3.166:9200" ]

# Password for the 'elastic' user generated by Elasticsearch
ELASTIC_PASSWORD = "mypasswd"

# Create the client instance
es = Elasticsearch(
    NODES,
    ca_certs="/MyWorkSpace/elastic-stack-metal-install/elasticsearch-8.5.1/config/certs/http_ca.crt",
    basic_auth=("elastic", ELASTIC_PASSWORD)
) 

resp = es.get(index="test-index", id=5)
print(resp)

 

 

Kibana Web GUI로 결과 확인하기

Kibana Web GUI의 'dev tool'을 이용하여 아래와 같이 index, document를 조회할 수 있다.

Kibana Web UI

 

위 Web GUI에서 사용했던 Elasticsearch Query 참고.
##
## Index 정보를 가져온다.
##

GET _cat/indices?v

## 응답은 이런 모양이다.
health status index           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   example-index-0 Up1jqY3PTG2pLHdOLJcLGQ   1   1   18126912          739      2.9gb          2.9gb
yellow open   test-index      nGaLdNNORHKfJF1maBlNvw   1   1          2            0     11.2kb         11.2kb




##
## "example-index-0" 인덱스에 있는 모든 document 중에서 3개만 가져온다.
##

GET example-index-0/_search?size=3
{  
  "query": {
    "match_all": { }
  }
}
 

##
## "app" 항목 중에서 "server"라는 어휘가 포함돠ㅣㄴ 문서를 모두 가져온다.
##

GET example-index-0/_search
{  
  "query": {
    "match": { "app": "server" }
  }
}


##
## "mac-address" 항목 중에서 정확하게 "0e:c3:0d:97:ba:f0" 와 일치하는 document만 가져온다.
##

GET example-*/_search
{  
  "query": {
    "match_phrase": { "mac-address": "0e:c3:0d:97:ba:f0" }
  }
}


##
## Elasticsearch Cluster 상태 정보를 가져온다. 
##

GET /_cluster/state

GET /_cluster/state?filter_path=metadata.indices.*.stat*

GET /example-index-0/_stats


##
## Elasticsearch Cluster에 저장된 전체 Document 개수를 가져온다.
##

GET /_count


##
## 위 _count 정보 중에서 _shard 정보를 제외한 정보를 가져온다.
##

GET /_count?filter_path=-_shards

 

 

반응형

Elastic 가이드 북 (김종민 님)

업무 때문에 1~2일 이내에 잽싸게 Elastic을 스터디하고, ElasticSearch를 설치 및 Client App을 개발해야 하는데 어디서 부터 봐야 하는지 막막했다.

그러다가 찾은 Web Docs가 김종민 님의 "Elastic 가이드 북" 이었다.

 

https://esbook.kimjmin.net/

 

Elastic 가이드 북 - Elastic 가이드북

7. 인덱스 설정과 매핑 - Settings & Mappings

esbook.kimjmin.net

 

위 Elastic 가이드 북을 읽고, Elastic에 관해 두루두루 이해를 하고 깊게 봐야 하는 것만 Elastic 공식 Web Site에서 Document를 보면 딱 좋다.

 

 

Elastic Official Guide Documents

Elasticsearch 및 그 주변의 Stack Tool에 관한 모든 것이 다 설명되어 있다.

게다가 Elasticsearch Client API도 Programming Language 별로 설명 및 Example이 잘 작성되어 있다.

Elasticsearch를 사용하다가 궁금하거나 필요한 정보가 있다면, 이 Official Guide Docs를 보는 것이 좋다.

 

 

 

Welcome to Elastic Docs | Elastic

 

www.elastic.co

 

 

 

 

ElasticSearch REST API Example

내가 많이 사용하는 검색 예시이다. 급할 때 참고해서 작성하면 좋을 듯...

 

## 참고: 아래 HTTP REST API 예시는 Kibana의 [Dev Tools] UI에서 수행하기 !!!


##
## index 목록과 요약 정보(Document 개수, 용량) 조회하기
##
GET _cat/indices?v

## 응답은 이렇다.
health status index           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   example-index-0 Up1jqY3PTG2pLHdOLJcLGQ   1   1   18126912          739      2.9gb          2.9gb
yellow open   test-index      nGaLdNNORHKfJF1maBlNvw   1   1          2            0     11.2kb         11.2kb




##
## "ALARM" 문자열이 있는 Document를 탐색
##

GET _search?size=50
{
  "query": {
    "match": {
      "message": "ALARM"
    }
  }
}


##
## "kubernetes.container_name": "apiserver" 인 Document를 탐색
##

GET _search?size=50
{
  "query": {
    "match": {
      "kubernetes.container_name": "apiserver"
    }
  }
}


##
## Pod labels에 "vendor=KingSejong" 설정된 Pod가 출력만 로그(즉, Docs)만 검색
##

GET app-*/_search?size=30
{
  "query": {
    "match": {
      "kubernetes.flat_labels": "vendor=KingSejong",
    }
  }
}


##
## Index가 app-000051인 문서 전체를 열람
##

GET app-000051/_search
{
  "query": {
    "match_all": {}
  }
}


##
## Pod의 labels에 "app=my-test-app"가 설정되어 있는 Pod가 출력한 로그 중에서
## 로그의 내용이 "CREATE" 문자열을 포함하는 Document만 검색
##

GET _search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "kubernetes.flat_labels": "app=my-test-app"
          }
        },
        {
          "match_phrase": {
            "message": "CREATE"
          }
        }
      ]
    }
  }
}

 

 

 

 

CURL 명령으로 Elasticsearch의 Index, Document를 조회, 생성하는 예제

아래 Blog에 작성된 예제 코드를 그대로 따라하면,

  • Index
    • 생성, 삭제, 리스트를 조회, 특정 Index를 조회하는 것을 할 수 있다.
  • Document
    • 생성, 삭제, 리스트를 조회, 특정 Document를 조회하는 것을 할 수 있다.

 

https://twofootdog.tistory.com/55

 

Elasticsearch REST API 사용하기(인덱스, 도큐먼트 CRUD)

Elasticsearch에서 인덱스(index)와 도큐먼트(document)를 조회/등록/변경/삭제 등을 수행하기 위해서는 REST API를 호출하게 된다. 이번 글에서는 Elasticsearch에서 사용하는 API에 대해 알아보고자 한다. 1.

twofootdog.tistory.com

 

반응형

 

REST API Server

Go 기본 Package만 사용해서 REST API Server 만들기

일단, 아래 블로그가 예제 코드를 복사해서 실습하기 좋게되어 있다.

https://woony-sik.tistory.com/12

 

Golang REST API 만들기

오늘은 Golang으로 간단한 REST API를 만드는 방법을 쓸까 한다. 바로 시작하자 우선은 Directory를 하나 만들고 시작 mkdir rest go module 등록 go mod init noah.io/ark/rest main.go 생성 touch main.go Direc..

woony-sik.tistory.com

 

 

gorilla package의 mux를 이용해서 REST API Server 만들기

이 블로그는 자동 Test하는 Code까지 포함되어 있다.

따라서 상용 Software PKG 개발할 때, 참고하면 좋다.

 

https://velog.io/@soosungp33/Golang%EC%9C%BC%EB%A1%9C-%EC%9B%B9%EC%84%9C%EB%B2%84-%EB%A7%8C%EB%93%A4%EA%B8%B04

 

 

Golang으로 웹서버 만들기(4)

RESTful API - GET과 POST 다뤄보기

velog.io

 

 

 

REST API Client

go-resty 라는 'REST client library'를 이용하면, 쉽게 REST API Client App을 개발할 수 있다.

아래 GitHub에 Case by Case로 Example이 있기 때문에 장황한 설명보다는 아래 Web Docs에 있는 Example Code를 보고 이해하고 따라해보는 것이 좋을 듯하다.

https://github.com/go-resty/resty
 

GitHub - go-resty/resty: Simple HTTP and REST client library for Go

Simple HTTP and REST client library for Go. Contribute to go-resty/resty development by creating an account on GitHub.

github.com

 

go-resty를 소개한 블로그이다. 쉽게 설명했으니까 한번 읽어보면 좋을 것이다.

go-resty를 사용하면, JSON Type의 Request / Response 를 Marshal, Unmarshal할 필요가 없다.

 

https://wookiist.dev/104
 

[Go/Golang] Go의 HTTP & REST Client 라이브러리 - Resty

Go의 HTTP & REST Client 라이브러리 - Resty API Client 이전 포스팅에서 다뤘던 Echo는 Go의 Web Framework입니다. Echo로 구현한 프로그램은 API Server 등으로 동작할 수 있고, 큰 어려움 없이 Web Server로..

wookiist.dev

 

 

 

 

 

기타 Reference 하면 좋을 Blog

 

https://doitnow-man.tistory.com/259

 

[Go Lang] 4. 실전 - http server + swagger 만들기

목표 web framework를 사용하여 간단한 web api server를 만들어 보겠습니다. 배포는 추후 포스트에서 다루겠습니다. 개발 환경 - ubnutu 18.04 - go version go1.16.3 linux/amd64 (업그레이드 방법: golang.org..

doitnow-man.tistory.com

 

 

블로그 작성자: sejong.jeonjo@gmail.com

 

 

반응형

 

장황한 설명보다는 예제가 이해가 쉬울 듯하여, 아래의 예제 코드를 작성했다.

 

 

Case:  Kubernetes Cluster 외부에서 Kubernetes Cluster 내부 Service에 접근

아래와 같은 Server, Client App의 구성을 가정하고 아래 예제를 따라해본다.

  • Server App 위치: Kubernetes Cluster 내부
  • Client App 위치: Kubernetes Cluster 외부

 


API 접근용 TOKEN 값을 알고 있다면, 바로 아래 예제를 따라서 수행하면 된다.

 

$  cat curl-pod-list.sh
##
## Create a Pod on myspace namespace
##

TOKEN=$(oc whoami -t)
ENDPOINT="https://api.ocp4.mycluster.io:6443"
NAMESPACE="myspace"

echo ""
echo "TOKEN:     $TOKEN"
echo "ENDPOINT:  $ENDPOINT"
echo "NAMESPACE: $NAMESPACE"
echo ""


##
## Get Pod list in a namespace
##

RESPONSE_FILE=./curl-pod-list-response.json

curl -v -k -o $RESPONSE_FILE \
    -H "Authorization: Bearer $TOKEN" \
    -H 'Accept: application/json' \
    $ENDPOINT/api/v1/namespaces/$NAMESPACE/pods


cat $RESPONSE_FILE


echo ""
echo "====================================================="
echo "                     Summary                         "
echo "====================================================="
echo ""

jq '.items[] | {PodName: .metadata.name, PodIP: .status.podIPs, StartTime: .status.startTime, Node: .spec.nodeName}' curl-pod-list-response.json

$

 

 

Case:  Kubernetes Cluster 내부에서 Kubernetes Cluster 내부 Service에 접근

아래와 같은 Server, Client App의 구성을 가정하고 아래 예제를 따라해본다.

  • Server App 위치: Kubernetes Cluster 내부
    • Server는 Elasticsearch API Server 역할
  • Client App 위치: Kubernetes Cluster 내부

즉, Cluster 내부에서 Pod간 통신이라고 가정한다.

 


[ 참고 ]
API 접근용 TOKEN은Pod 내부의 /var/run/secrets/kubernetes.io/serviceaccount/token 파일에 있다.
ServiceAccount 별로 Token을 생성하고 서비스 접근 권한을 부여하기 때문에 Client App 역할을 하는 Pod가 사용하는 ServiceAccount에게 Server Pod의 Service에 접근할 수 있도록 Role을 Binding해줘야 한다. 

 

 

$  cat clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-my-service-account
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: system:serviceaccount:my-namespace:my-service-account
  
  $  kubectl apply -f clusterrolebinding.yaml

 

 

#!/bin/bash


##
## Run this script in my example pod !
##
##  1) Jump into my example pod
##     $  kubectl exec -n my-namespace -it my-example-pod -- bash
##
##  2) Run this script in the above pod
##     $  chmod +x run-es-query-in-container.sh
##     $  ./run-es-query-in-container.sh
##


TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
ENDPOINT="https://elasticsearch.openshift-logging:9200"
RESPONSE_FILE=curl-es.json

rm  $RESPONSE_FILE

echo ""
echo "TOKEN:     $TOKEN"
echo "ENDPOINT:  $ENDPOINT"
echo ""


curl -k -o $RESPONSE_FILE \
    -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -d '{ "query": { "match": { "message": "cm-apiserver" } } }' \
    $ENDPOINT/infra-000094/_search?size=3



jq ".hits.hits[]._source | { kubernetes, message }" $RESPONSE_FILE

+ Recent posts