iOrchard http://www.iorchard.net/ Virtualization, Cloud Computing Expert Group en-us Thu, 22 Sep 2022 00:00:00 +0900 http://www.iorchard.net/2022/09/22/demo_provision_k8s_cluster_on_pbos_using_pulumi.html http://www.iorchard.net/2022/09/22/demo_provision_k8s_cluster_on_pbos_using_pulumi.html <![CDATA[Demo: Provision K8S cluster on PBOS using pulumi]]> Demo: Provision K8S cluster on PBOS using pulumi

This is the demo of Provisioning K8S Cluster on PBOS platform using Pulumi.

PBOS is an ansible playbook suite to install OpenStack on Baremetal. PBOS stands for Pure Baremetal OpenStack.

Pulumi is an IaC tool.

Demo

screencast

]]>
Thu, 22 Sep 2022 00:00:00 +0900
http://www.iorchard.net/2021/09/23/demo_pbos_installation.html http://www.iorchard.net/2021/09/23/demo_pbos_installation.html <![CDATA[Demo: PBOS Installation]]> Demo: PBOS Installation

PBOS is an ansible playbook suite to install OpenStack on Baremetal. PBOS stands for Pure Baremetal OpenStack.

There are 1 playbook and 16 roles in PBOS.

PBOS has 3 groups.

  • pbos-infra: HA and infrastructure related components
  • pbos-storage: Backend Storage (It supports Ceph and LVM/iSCSI)
  • openstack: OpenStack components

Demo

screencast

]]>
Thu, 23 Sep 2021 00:00:00 +0900
http://www.iorchard.net/2021/03/04/okidoki_vm_high_availability_for_openstack.html http://www.iorchard.net/2021/03/04/okidoki_vm_high_availability_for_openstack.html <![CDATA[OkiDoki - VM High Availability for OpenStack]]> OkiDoki - VM High Availability for OpenStack

OkiDoki is a project to achieve VM High Availability for OpenStack platform.

It uses Masakari, Corosync, and Pacemaker.

  • Masakari: provides Instances High Availability Service for OpenStack

    • recover KVM-based Virtual Machine(VM)s from failure events
    • an API service to manage and control the automated rescue mechanism
  • Cluster stack: Corosync, Pacemaker, Pacemaker-remote for HA

    • Corosync: cluster engine
    • Pacemaker: resource manager
    • Pacemaker-remote: lightweight resource manager for scalability. (corosync/pacemaker cluster has a limit of 16 nodes.)

OkiDoki Components

  • Controller nodes

    • corosync/pacemaker
    • masakari-api: Get notifications of instance/host failures from monitor
    • masakari-engine: Process recovery workflow for instance/host failure
  • Compute nodes

    • pacemaker-remote
    • masakari-instancemonitor
    • masakari-hostmonitor

masakari-processmonitor is not used by OkiDoki because openstack components are running as pods on kubernetes system. Kubernetes itself can handle nova-compute service failure.

Demo

screencast

]]>
Thu, 04 Mar 2021 00:00:00 +0900
http://www.iorchard.net/2021/03/04/sparring_a_test_robot_suite_for_openstack_platform.html http://www.iorchard.net/2021/03/04/sparring_a_test_robot_suite_for_openstack_platform.html <![CDATA[Sparring - a test robot suite for OpenStack platform]]> Sparring - a test robot suite for OpenStack platform

Sparring is a test robot suite for OpenStack platform.

There are 3 robots for now.

  • funcbot: a functional test robot for openstack
  • perfbot: a performance test robot for openstack
  • cdbot: a continuous deployment test robot for openstack API services

funcbot

  • Use robotframework and gabbi library for functional tests

  • There are 5 test suites

    • identity: Keystone API test
    • network: Neutron API test
    • image: Glance API test
    • volume: Cinder API test
    • compute: Nova API test
  • There are 3 areas - Keyword, Code, Manifest

    • Keyword: This area is for tester. Just put keywords from Code area.
    • Code: This area is for programmer. Program logic of keywords are here.
    • Manifest: This area is for programmer. OpenStack API calls are here.

Keyword example: Given-When-Then example:

Start the server
  [Tags]    compute     critical
  Given Compute service is available
  When Start the server
  Then Check if the server is active

Code example: Use robotframework libraries:

Check if the server is active
  Wait Until Keyword Succeeds   2m   3s
  ...   check server is active     url=${COMPUTE_SERVICE}

Manifest example: API manifests are defined in yaml format using gabbi:

- name: check server is active
  GET: /servers/$ENVIRON['TEST_SERVER_ID']
  status: 200
  response_json_paths:
    $.server.status: ACTIVE

How to use funcbot

Get the sample openstack_settings.robot file to /tmp/ and Edit settings above “Do not touch below!!!” line.:

docker run --rm --name sparring jijisa/sparring \
     --show-os-settings > /tmp/settings.robot

To run all test suites in funcbot (This is default.):

docker run --rm --tty --network=host --name sparring \
  -v /etc/hosts:/etc/hosts:ro -v /tmp/output:/tmp/output \
  -v /tmp/settings.robot:/sparring/resources/openstack_settings.robot:ro \
  jijisa/sparring

To run specific test suites(e.g. network and image) in funcbot:

docker run --rm --tty --network=host --name sparring \
  -v /etc/hosts:/etc/hosts:ro -v /tmp/output:/tmp/output \
  -v /tmp/settings.robot:/sparring/resources/openstack_settings.robot:ro \
  jijisa/sparring --run-funcbot network image

To run all test cases except evacuation test in funcbot (funcbot forces compute service down to evacuate test VM instance so the option(-e) excluding evacuation test is useful when you run Sparring funcbot in production environment.):

docker run --rm --tty --network=host --name sparring \
  -v /etc/hosts:/etc/hosts:ro -v /tmp/output:/tmp/output \
  -v /tmp/settings.robot:/sparring/resources/openstack_settings.robot:ro \
  jijisa/sparring --run-funcbot -e

Deliverables

Demo

screencast

]]>
Thu, 04 Mar 2021 00:00:00 +0900
http://www.iorchard.net/2020/01/29/쿠버네티스_컨테이너_인터페이스_식별하는_방법.html http://www.iorchard.net/2020/01/29/쿠버네티스_컨테이너_인터페이스_식별하는_방법.html <![CDATA[쿠버네티스 컨테이너 인터페이스 식별하는 방법]]> 쿠버네티스 컨테이너 인터페이스 식별하는 방법

쿠버네티스 환경에서 특정 컨테이너의 인터페이스를 모니터할 일이 생겼는데,

해당 컨테이너 인터페이스의 pair가 어떤건지 식별하는 방법을 모르겠어서 이곳에 기록하고 공유한다.

먼저 찾으려는 pod의 pause 컨테이너ID를 찾는다.:

$ sudo docker ps |grep proxy-nginx
89a1d0a081f3        5a3221f0137b                                      "nginx -g xy-nginx-576d4fd9cd-4gprn_fd790dd7-3c0b-11ea-be0d-e4434b6e257c_0
221c4add4238        google_containers/pause-amd64:3.1                 "/pause"  -nginx-576d4fd9cd-4gprn_fd790dd7-3c0b-11ea-be0d-e4434b6e257c_0
  • 두 번째 컨테이너인 221c4add4238가 네트워크 네임스페이스를 공유하는 pause 컨테이너이다.

pause 컨테이너의 ID를 가지고 pid를 찾는다.:

$ sudo docker inspect --format '{{ .State.Pid }}' 221c4add4238
68855

찾은 pid를 가지고 해당 pid의 네트워크 네임스페이스 안에서 인터페이스 인덱스를 식별한다.:

$ sudo nsenter -t 68855 -n ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
3: eth0@if232: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 36:e4:45:56:18:99 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.206.132/32 scope global eth0
       valid_lft forever preferred_lft forever
  • 컨테이너의 인터페이스인 eth0과 pair 맺은 인터페이스 인덱스는 232번 이다.

이제 호스트에서 인덱스 232 번 인터페이스를 찾는다.:

$ ip a |grep 232
232: cali29544dc48cd@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  • cali29544dc48cd인터페이스임을 알 수 있다.

reference

]]>
Wed, 29 Jan 2020 00:00:00 +0900
http://www.iorchard.net/2019/07/30/gitlab_간략_사용법.html http://www.iorchard.net/2019/07/30/gitlab_간략_사용법.html <![CDATA[GitLab 간략 사용법]]> GitLab 간략 사용법

[개요]

GitLab 사용에 기본이 될수 있는 프로젝트 생성부터, git clone, push, pull 에 대한 내용을 간략하게 보여줍니다.

아래 환경은 웹페이지 + 리눅스 bashShell 기반으로 작성합니다.

그리고 git 미설치 상태이시면 “apt install git” 으로 git 패키지를 설치 합니다.

1.project 초대

2.git config

3.git clone, add, commit, push

4.기존, 새로운 폴더 push

5.git pull

1.project 초대

프로젝트 선택후 아래의 이미지를 따라 갑니다.

../../../_images/프로젝트초대1.jpg
../../../_images/프로젝트초대2.jpg

Select members to invite, permission, 등을 선택후 Add to project 합니다.

2.git config

이름, E-mail 등록:

git config --global user.name "orchard"

git config --global user.email "support@iorchard.co.kr"

config 확인:

# git config --list

user.name=orchard
user.email=support@iorchard.co.kr

3.git clone, add, commit, push

git clone:

# git clone http://192.168.0.161/Min/testproject.git

Cloning into 'testproject'...
warning: You appear to have cloned an empty repository.

clone 확인:

# ls

testproject

폴더만 생성된 상태이고 경로 안에는 아무것도 없는 상태 입니다.

빈 깡통의 폴더로 접근하여 파일 생성, commit, push 합니다.:

# cd testproject

touch index.html

아래는 리스트로 파일 생성 확인:

# ls

index.html

위의 생성된 파일로 commit 전에 git add 합니다.:

# git add index.html

git add ‘파일명’ 이 아닌

“git add .” 으로 생성된 모든 것을 git add 가능

git commit 시도 ‘-m’ 옵션으로 메세지를 남겨 주어야 한다.:

# git commit -m "messa..."

[master (root-commit) 26b8fde] messa...
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 index.html

commit 이후 마지막 단계 git push

‘git push -u origin 브랜치명’ - 현재 브랜치명은 master로 되어 있음.

브랜치는 사용자 기호에 따라 추가 가능.

 git push -u

Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 207 bytes | 207.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://192.168.0.161/Min/testproject.git
...

push 이후 웹페이지 확인

../../../_images/git_push.jpg

위 이미지로 index가 push 된걸 알수 있다.

4.기존, 새로운 폴더 push

기존 자신이 가지고 있던 소스를 push 하기 위해 사용될것으로 보입니다.

Tip. GitLab의 새로운 프로젝트 생성후 프로젝트 경로의 공간이 비워 있는상태에서 push 하는 추천.

해당 폴더로 접근후 git init 해준다.:

# cd forder

#  git init
Initialized empty Git repository in /Users/sunmin/Desktop/gittest/forder/.git/

remote 저장소 등록 후 push 까지:

# git remote add origin http://192.168.0.161/Min/testproject2.git

# git add .

# git commit -m "forder"

On branch master
nothing to commit, working tree clean

# git push -u origin master

Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 203 bytes | 203.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://192.168.0.161/Min/testproject2.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

5.git pull

다른 누군가가 추가 파일을 업로드해 둔게 있다면 pull 로 당겨 온다.:

# git pull

remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From http://192.168.0.161/Min/testproject
   26b8fde..1eeef43  master     -> origin/master
Updating 26b8fde..1eeef43
Fast-forward
 test1 | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 test1

‘git pull origin 브랜치명’ 으로 특정 브랜치의 pull 도 가능 하다.

]]>
Tue, 30 Jul 2019 00:00:00 +0900
http://www.iorchard.net/2019/07/01/테스트_서버_uxen3_기능시험.html http://www.iorchard.net/2019/07/01/테스트_서버_uxen3_기능시험.html <![CDATA[테스트 서버 UXEN3 기능시험]]> 테스트 서버 UXEN3 기능시험

[개요]

브라운스톤 사무실 이사후 UXEN3 테스트 서버 구축 완료. ( AOE 이슈 문제 제외하고 완료)

서초 UXEN3 기능시험서를 참고 하여 테스트 한다.

기능시험 테스트환경이 알맞은지는 모르겠지만, 시작해 본다. ( 알맞은 환경이 아니면 기능시험에 맞는 환경을 구성하고 다시 시험 할 것임)

기능시험서에 하드웨어 구성 및 패키지 버젼 확인후 vm create 부터 시작.

dwade VM 에서 시험

iscsi volume의 gvm을 사용

storlink 는 local 사용

Tip]

  • /opt/uxen3/var/log/uxenapi.log 를 확인하면서 실제 어떤 명령이 떨어지는지 확인해 본다.

  • 아래의 모든 내용을 실행결과 uxencli 관련명령어로 수행 되는 실제 명령어 들은

    qemu-img covert

    qemu-img create

    DB 정보 변경

위의 3가지 위주로 이루어 진다.

command line 이후 comment가 없는 부분은 기능 정상임.

VM 관련기능.

1.VM Create:

# uxencli vm-add Uxen3TestVM 1b14c1cd-a374-406c-b1e4-5be320c1cad6 1 1 1024 2048 "Uxen3 Test VM" xenbr0 xenbr1
Success

2.VM Start:

# uxencli vm-start ad9275d2-92df-40be-9fc2-de10457d3c1e
Success

3.VM Copy - Online:

# local storlink VM을 local storlink로 Online으로 copy

# uxencli vm-copy ad9275d2-92df-40be-9fc2-de10457d3c1e Uxen3TestVMcopy 1
Success

Online으로 copy 후 VM 구동시 구동은 되지만 아래의 에러가 나타남.:

xen:manage: setup_shutdown_watcher: Error -13 writing feature-poweroff

3.VM Copy - Offline:

# uxencli vm-copy ad9275d2-92df-40be-9fc2-de10457d3c1e Uxen3TestVMcopy2 1
Success

Online copy와 동일한 에러가 있다.:

xen:manage: setup_shutdown_watcher: Error -13 writing feature-poweroff

새로 생성하는 VM에서도 똑같은 에러가 보이는것으로 보아 큰 문제점은 아닌것으로 보인다.

4.VM Delete:

# uxencli vm-del 496b3e6a-6b38-48c6-b9cb-204336cf1393
Success

Delete 전:

ls
292e588f-549e-4aa1-a4e8-9f21b7efed0a  35e8eea5-19d6-4023-9c42-1025b32819d6
33f5ca20-45ac-4159-8480-294654691b10  4f6c5c69-2bb4-4ec4-a856-2b69b865343d

Delete 후:

ls
292e588f-549e-4aa1-a4e8-9f21b7efed0a  35e8eea5-19d6-4023-9c42-1025b32819d6  4f6c5c69-2bb4-4ec4-a856-2b69b865343d

5.VM Disk Create - Online:

# uxencli vm-disk-add ad9275d2-92df-40be-9fc2-de10457d3c1e 20000 1 "disk add test1"
Success

# uxencli vm-disk-list ad9275d2-92df-40be-9fc2-de10457d3c1e
DISK_UUID                            STORLINK SIZE   FORMAT ORDER
4f6c5c69-2bb4-4ec4-a856-2b69b865343d 1        30720  qcow2  1
2d010062-8fc5-44c4-9d15-1af96ff96595 1        20000  qcow2  2

5.VM Disk Create - Offline:

# uxencli vm-disk-add ad9275d2-92df-40be-9fc2-de10457d3c1e 19000 1 "disk add test2"
Success

# uxencli vm-disk-list ad9275d2-92df-40be-9fc2-de10457d3c1e
DISK_UUID                            STORLINK SIZE   FORMAT ORDER
4f6c5c69-2bb4-4ec4-a856-2b69b865343d 1        30720  qcow2  1
2d010062-8fc5-44c4-9d15-1af96ff96595 1        20000  qcow2  2
3744167b-5104-4217-aeb6-c6c7a19247f8 1        19000  qcow2  3

6.VM Disk Delete - Online:

# uxencli vm-disk-del ad9275d2-92df-40be-9fc2-de10457d3c1e 3744167b-5104-4217-aeb6-c6c7a19247f8
Failure (Bad Request) : {"message":"The VM should not be running.","result":102}

6.VM Disk Delete - Offline:

# uxencli vm-disk-del ad9275d2-92df-40be-9fc2-de10457d3c1e 3744167b-5104-4217-aeb6-c6c7a19247f8
Success

# uxencli vm-disk-list ad9275d2-92df-40be-9fc2-de10457d3c1e
DISK_UUID                            STORLINK SIZE   FORMAT ORDER
4f6c5c69-2bb4-4ec4-a856-2b69b865343d 1        30720  qcow2  1
2d010062-8fc5-44c4-9d15-1af96ff96595 1        20000  qcow2  2

7.VM Disk List:

# uxencli vm-disk-list ad9275d2-92df-40be-9fc2-de10457d3c1e
DISK_UUID                            STORLINK SIZE   FORMAT ORDER
4f6c5c69-2bb4-4ec4-a856-2b69b865343d 1        30720  qcow2  1
2d010062-8fc5-44c4-9d15-1af96ff96595 1        20000  qcow2  2

8.VM information:

# uxencli vm-info ad9275d2-92df-40be-9fc2-de10457d3c1e
UUID            : ad9275d2-92df-40be-9fc2-de10457d3c1e
Name            : Uxen3TestVM
Cpu             : 1
Maxmem          : 2048
Memory          : 1024
OS              : DEBIAN
OS Arch         : X64
State           : RUNNING
GVM             : 1b14c1cd-a374-406c-b1e4-5be320c1cad6
Created         : 2019-06-24T07:36:57.292553Z
Recent Booted   : 2019-06-25T06:42:18.874897Z
Networks        : [ifname] [mac]
                  xenbr1   00:16:3E:BD:ED:6B
                  xenbr0   00:16:3E:63:97:8E
VNC Port        : 5902
VNC Password    : 9zh04lvst5x8

9.VM List:

# uxencli vm-list
UUID                                 NAME         vCPU MEM    STATUS     PM
85c019e1-6eac-4cd1-b732-0a331632dd56 a_g_disk2_t  1    1024   SHUTDOWN   -
40edeb71-dc4b-4b77-9156-856f64271419 bondvm       1    1024   SHUTDOWN   -
ad9275d2-92df-40be-9fc2-de10457d3c1e Uxen3TestVM  1    1024   RUNNING    E0A697BE-C47E-DD11-98FB-0023540D61DA
af09497e-51be-4b60-bbf6-e36f38e32ab8 gitlab_t     2    2048   RUNNING    A064D172-E07E-DD11-91FE-0023541104C2
3fcf68de-f08f-4de7-952c-471795ba6bdf a_w_i_t      1    1024   SHUTDOWN   -
6846366b-4430-4139-84cd-7bc05e968d21 iscsivm      1    1024   RUNNING    E0A697BE-C47E-DD11-98FB-0023540D61DA
31eaec7b-b031-4226-821e-7c892aaebdb7 jennie_nfs_vm 1    1024   RUNNING    A064D172-E07E-DD11-91FE-0023541104C2
deaf14fc-f7d6-43d8-8712-218afb8037db jennie_aoe_vm 1    1024   RUNNING    A064D172-E07E-DD11-91FE-0023541104C2

10.VM Shutdown:

# uxencli vm-shutdown ad9275d2-92df-40be-9fc2-de10457d3c1e
Success

11.VM Poweroff:

# uxencli vm-poweroff ad9275d2-92df-40be-9fc2-de10457d3c1e
Success

12.VM Reboot:

# uxencli vm-reboot ad9275d2-92df-40be-9fc2-de10457d3c1e
Success

13.VM State:

# uxencli vm-stat ad9275d2-92df-40be-9fc2-de10457d3c1e
UUID            : ad9275d2-92df-40be-9fc2-de10457d3c1e
Name            : Uxen3TestVM
CPU cores       : 1
CPU util.       : 0.1 %
Memory          : 1024
Networks        : [ifname] [rx_sum]           [tx_sum]
                  total    1862               81540
                  xenbr1   0                  28783
                  xenbr0   1862               52757

14.VM Suspend:

# uxencli vm-suspend ad9275d2-92df-40be-9fc2-de10457d3c1e
Success

# uxencli vm-list
UUID                                 NAME         vCPU MEM    STATUS     PM
ad9275d2-92df-40be-9fc2-de10457d3c1e Uxen3TestVM  1    1024   SUSPEND    E0A697BE-C47E-DD11-98FB-0023540D61DA

VM이 중지 되며, VNC 로는 접속이 가능 하다. 단 멈춰 있다.

ssh 는 접속이 가능 할까?

접속 불가… 중지된 VM에 PING 테스트도 불가능.

15.VM Resume:

# uxencli vm-resume ad9275d2-92df-40be-9fc2-de10457d3c1e
Success

16.VM Update - cpu add Online:

# uxencli vm-update ad9275d2-92df-40be-9fc2-de10457d3c1e 2 1024 2048
Success

Online으로 cpu가 core가 올라가지 않는다.

reboot으로도 변경 되지 않는다.

shutdown 이후 start로 다시 켜줘야 정상 반영됨.

16.VM Update - cpu Delete Online:

# uxencli vm-update ad9275d2-92df-40be-9fc2-de10457d3c1e 1 1024 2048
Success

Online으로 cpu가 줄어 들지 않는다.

cpu add 처럼 Online으로 delete 반영 불가

reboot으로도 안된다. shutdown, start를 거쳐야 한다.

16.VM Update - mem add Online:

# uxencli vm-update ad9275d2-92df-40be-9fc2-de10457d3c1e 1 2048 2048
Success

MEM ADD는 바로 반영됨

16.VM Update - mem delete Online:

# uxencli vm-update ad9275d2-92df-40be-9fc2-de10457d3c1e 1 1024 2048
Success

mem을 온라인으로 줄이면 위 그림과 같이 조금씩 줄어드는 모습을 확인 가능.

16.VM Update - mem Offline Add:

# uxencli vm-update ad9275d2-92df-40be-9fc2-de10457d3c1e 1 2024 2048
Success

mem add Offline으로 가능.

16.VM Update - mem Offline Delete:

# uxencli vm-update ad9275d2-92df-40be-9fc2-de10457d3c1e 1 1024 2048
Success

mem delete offline으로 가능.

mem 수정은 자유로우나 cpu 수정은 자유롭지 못한것으로 보인다.

17.VM vif Add - Online,Offline:

# uxencli vm-vif-add ad9275d2-92df-40be-9fc2-de10457d3c1e xenbr1
Success

# uxencli vm-vif-list ad9275d2-92df-40be-9fc2-de10457d3c1e
ID   VIF_NAME   BRIDGE  MAC
31   2zrzn0xd1  xenbr1  00:16:3E:BD:ED:6B
30   tng7fs0bg  xenbr0  00:16:3E:63:97:8E
36   05j4mliyz  xenbr1  00:16:3E:39:C9:CD

18.VM vif Delete:

g# uxencli vm-vif-del ad9275d2-92df-40be-9fc2-de10457d3c1e 30
Failure (Bad Request) : {"message":"The VM should not be running.","result":114}

vif add는 Online,Offline 모두 가능하며, delete는 vm Offline에서만 가능 하다.

19.VM vif List

위의 17.번 내용에 List 출력 있음.

20.VM Storlink Migrate - Online:

# uxencli vm-smigrate ad9275d2-92df-40be-9fc2-de10457d3c1e 2
Success

Storlink를 옮겨 가는것으로 경로를 변경하는것이다.

disk의 경로 이동이 잘 되었나 확인하기 위해 disk-list를 볼려니 DB 에러가 나타난다.:

# uxencli vm-disk-list ad9275d2-92df-40be-9fc2-de10457d3c1e

Traceback (most recent call last):
  File "/opt/uxen3/script/uxencli", line 1175, in <module>
    cli(obj={})
  File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/opt/uxen3/script/uxencli", line 836, in vm_disk_list
    format(data['uuid'], data['storlink'], data['size'],
TypeError: string indices must be integers

VM을 shutdown,start 를 거치니 정상적으로 disk-list 출력됨.

20.VM Storlink Migrate - Offline:

# uxencli vm-smigrate ad9275d2-92df-40be-9fc2-de10457d3c1e 1
Failure (Bad Request) : {"message":"The VM should run for storage migration.","result":203}

VM 미구동 상태에서 smigrate 가 불가 한것으로 보인다. 구동후 다시 시도:

# uxencli vm-start ad9275d2-92df-40be-9fc2-de10457d3c1e
Success

# uxencli vm-smigrate ad9275d2-92df-40be-9fc2-de10457d3c1e 1
Success

disk 이미지가 유실 되었다. smigrate는 사용하면 안되는것으로 보인다.

21.VM Migrate - Online:

# worthy -> dwade
# uxencli vm-migrate f9423a1a-2a51-47b9-be0c-8b1fffa4935c  E0A697BE-C47E-DD11-98FB-0023540D61DA

Failure (Bad Request) : {"message":"Fail to migrate The VM.","result":219}


# dwade -> worthy
# uxencli vm-migrate 6d8229ad-559d-4421-9cb6-0bc5a5e136b8 A064D172-E07E-DD11-91FE-0023541104C2

Failure (Bad Request) : {"message":"Fail to migrate The VM.","result":219}

똑같은 PC의 CPU? 체계 이면 Migrate가 된다고 들었다. 다르면 안될 가능성이 있다고 한다.

위의 상태로는 안되는것으로 보인다.

  • dwade cpu: Pentium(R) Dual-Core CPU E6300 @ 2.80GHz

  • worthy cpu: Intel(R) Core(TM)2 Quad CPU Q9400 @ 2.66GHz

    Storlink 관련기능은 dwade가 아닌 worthy 에서 진행

Snapshot관련 기능

Snapshot에 관한 설명이 조금 필요.

시스템 고장으로 정지했을때 복구 시점을 만들어 주는것이다.

전체 백업이 아닌 중간지점에 습냅샷을 찍어두는것으로 이해가 된다.

그냥 백업을 하면 되지? 스냅샷을 사용할 이유가 있나?

대용량, 큰 시스템의 백업은 많은 시간도 소요 되지만,

백업 중인 디렉토리의 파일을 사용자가 이동하게 된다면 해당 파일은 백업미디어에서 완전 분실 상태가 되어 안전한 백업이 되지 못함.

1.Snapshot Add:

# uxencli snapshot-add f9423a1a-2a51-47b9-be0c-8b1fffa4935c snap_test1 21 "snapshot test1"
Success

[2019-06-26 16:27:59] DEBUG [api:637] (True, [{'format': 'qcow2', 'order': 1, 'uuid': 'e8aade96-e42c-4052-8fa7-a9a41269b595', 'desc': 'Run snapshot disk(e8aade96-e42c-4052-8fa7-a9a41269b595) created from disk(428a24a6-7e1b-4e85-9887-32b109e6fddf)', 'type': 'RS', 'size': 30720}, {'format': 'qcow2', 'order': 1, 'uuid': '95c346c8-b983-4d27-83d5-5cf960a33466', 'desc': 'Saved snapshot disk(95c346c8-b983-4d27-83d5-5cf960a33466) created from disk(428a24a6-7e1b-4e85-9887-32b109e6fddf)', 'type': 'SS', 'size': 30720}])
[2019-06-26 16:27:59] DEBUG [api:2005] [{'format': 'qcow2', 'order': 1, 'uuid': 'e8aade96-e42c-4052-8fa7-a9a41269b595', 'desc': 'Run snapshot disk(e8aade96-e42c-4052-8fa7-a9a41269b595) created from disk(428a24a6-7e1b-4e85-9887-32b109e6fddf)', 'type': 'RS', 'size': 30720}, {'format': 'qcow2', 'order': 1, 'uuid': '95c346c8-b983-4d27-83d5-5cf960a33466', 'desc': 'Saved snapshot disk(95c346c8-b983-4d27-83d5-5cf960a33466) created from disk(428a24a6-7e1b-4e85-9887-32b109e6fddf)', 'type': 'SS', 'size': 30720}]

위의 로그 결과로 보아 Type: rs, ss 가 정상적으로 생성된것으로 확인됨.

그런데 Type: rs, ss는 무엇인가? 흠…

2.Snapshot Delete

3.4.5.를 실행후 Delete 시도:

# uxencli snapshot-del f9423a1a-2a51-47b9-be0c-8b1fffa4935c 10238a18-4a38-4f97-a49b-01f3aa74dbd8
Failure (Bad Request) : {"message":"The VM should not be running.","result":114}

# uxencli snapshot-del f9423a1a-2a51-47b9-be0c-8b1fffa4935c d80bbb06-2d88-43a8-9983-162b2c5530b5
Failure (Bad Request) : {"message":"The VM should not be running.","result":114}

VM 구동중일때 Delete 가능한것으로 보임.

shutdown 이후 시도:

# uxencli snapshot-del f9423a1a-2a51-47b9-be0c-8b1fffa4935c d80bbb06-2d88-43a8-9983-162b2c5530b5
Failure (Bad Request) : {"message":"Snapshot(d80bbb06-2d88-43a8-9983-162b2c5530b5) is a parent of other snapshots.","result":114}

다른 스냅샷의 부모 다???:

# uxencli snapshot-list f9423a1a-2a51-47b9-be0c-8b1fffa4935c
UUID                                 NAME                             PARENT
10238a18-4a38-4f97-a49b-01f3aa74dbd8 restored snapshot name(snap_test1) f9423a1a-2a51-47b9-be0c-8b1fffa4935c/d80bbb06-2d88-43a8-9983-162b2c5530b5
d80bbb06-2d88-43a8-9983-162b2c5530b5 snap_test1                       f9423a1a-2a51-47b9-be0c-8b1fffa4935c

그러면 restored.. 시점 snapshot-delete 해 보겠다.:

# uxencli snapshot-del f9423a1a-2a51-47b9-be0c-8b1fffa4935c 10238a18-4a38-4f97-a49b-01f3aa74dbd8
Success

restore 된 스냅샷이 있으면 restore 부터 제거해 줘야 되는것으로 확인.

3.Snapshot Disk List:

# uxencli snapshot-disk-list f9423a1a-2a51-47b9-be0c-8b1fffa4935c d80bbb06-2d88-43a8-9983-162b2c5530b5

DISK_UUID                            STORLINK SIZE   FORMAT TYPE ORDER
e8aade96-e42c-4052-8fa7-a9a41269b595 21       30720  qcow2  RS   1
95c346c8-b983-4d27-83d5-5cf960a33466 21       30720  qcow2  SS   1

4.Snapshot List:

# uxencli snapshot-list f9423a1a-2a51-47b9-be0c-8b1fffa4935c

UUID                                 NAME                             PARENT
d80bbb06-2d88-43a8-9983-162b2c5530b5 snap_test1                       f9423a1a-2a51-47b9-be0c-8b1fffa4935c

5.Snapshot Restore:

# uxencli snapshot-restore f9423a1a-2a51-47b9-be0c-8b1fffa4935c d80bbb06-2d88-43a8-9983-162b2c5530b5
Failure (Bad Request) : {"message":"The VM should not be running.","result":114}

Online 상태에선 불가 그래서 shutdown 이후 시도.:

# uxencli snapshot-restore f9423a1a-2a51-47b9-be0c-8b1fffa4935c d80bbb06-2d88-43a8-9983-162b2c5530b5
Success

# uxencli snapshot-list f9423a1a-2a51-47b9-be0c-8b1fffa4935c
UUID                                 NAME                             PARENT
10238a18-4a38-4f97-a49b-01f3aa74dbd8 restored snapshot name(snap_test1) f9423a1a-2a51-47b9-be0c-8b1fffa4935c/d80bbb06-2d88-43a8-9983-162b2c5530b5
d80bbb06-2d88-43a8-9983-162b2c5530b5 snap_test1                       f9423a1a-2a51-47b9-be0c-8b1fffa4935c

restore로 인해 NAME에 restored… 포인트가 생성된것을 확인.

여기서 부터 GVM 관련 기능.

1.GVM Add:

# uxencli gvm-add worthyTestGvm debian x64 "worthyTestGvm" 21 53e60b6b-5dd5-4f0a-9e9e-b26d90fbc513 qcow2
Success

2.GVM Copy from VM:

# uxencli gvm-copyfromvm f9423a1a-2a51-47b9-be0c-8b1fffa4935c test_copyfromvm 21 "copy"
Failure (Bad Request) : {"message":"The VM should be stopped.","result":203}

VM 중지하고 다시 시도:

# uxencli gvm-copyfromvm f9423a1a-2a51-47b9-be0c-8b1fffa4935c test_copyfromvm 21 "copy"
Success

Copy본으로 부팅 유무 확인을 위해 vm-add 이후 부팅:

# uxencli vm-add copyTest 15dfd489-5446-47d2-8eed-def949c485e7 21 1 1024 2048 "copyT"
Success

# uxencli vm-start e7ed04bb-60f1-41f0-b0fd-0fbd795f3335
Success

정상작동!!!!

3.GVM Delete - GVM 관련 1.2.4.5.6.을 모두 실행후 delete:

# uxencli gvm-del 15dfd489-5446-47d2-8eed-def949c485e7

Failure (Bad Request) : {"message":"VM linked to the template exists.","result":100}

위의 GVM으로 생성된 VM이 있으면 delete가 안되는것으로 보임

관련 VM 제거후 시도:

# uxencli gvm-del 15dfd489-5446-47d2-8eed-def949c485e7

Success

관련 vm 제거후 gvm 제거 성공!!

4.GVM Disk List:

# uxencli gvm-disk-list a5c3a910-d777-4c55-9d2d-73b0c62dac22

DISK_UUID                            STORLINK SIZE   FORMAT ORDER
53e60b6b-5dd5-4f0a-9e9e-b26d90fbc513 21       30720  qcow2  1

5.GVM List:

# uxencli gvm-list

UUID                                 NAME         SIZE   OS           ARCH
909f64a8-d476-4d51-b6c0-0c2edc5988b1 jaragvm      30720  DEBIAN       X64
c5dfd089-d4d9-4c04-92ab-176248055df1 jennie_aoe_gvm 30720  DEBIAN       X64
bd4d84ec-9ea5-4820-8e0c-8d327e482dfe jennie_nfs_gvm 30720  DEBIAN       X64
f8c19f91-ffa8-4350-b5a8-780211074366 worthy_debian9.9 30720  DEBIAN       X64
1b14c1cd-a374-406c-b1e4-5be320c1cad6 iscsi-gvm-debian9.9 30720  DEBIAN       X64
a5c3a910-d777-4c55-9d2d-73b0c62dac22 worthyTestGvm 30720  DEBIAN       X64

6.GVM Update:

# uxencli gvm-update 15dfd489-5446-47d2-8eed-def949c485e7 TTtest debian x64 "TTT"

{"desc": "TTT", "name": "TTtest", "os_arch": "X64", "os": "DEBIAN"}
Success

PM관련 기능

1.PM Information:

# uxencli pm-info

UUID            : A064D172-E07E-DD11-91FE-0023541104C2
Name            : worthy
CPU             : 4
Memory          : 8191
Networks        : [ifname] [ip]            [mac]
                  xenbr0   192.168.0.38    00:e3:3d:e8:00:be
                  xenbr1   10.0.0.38       00:23:54:11:04:c2
Created         : 2019-05-28T06:53:40.070080Z
Updated         : 2019-06-14T00:45:33.758190Z

2.PM List:

# uxencli pm-list

UUID                                 NAME         CPU  MEM
A064D172-E07E-DD11-91FE-0023541104C2 worthy       4    8191
E0A697BE-C47E-DD11-98FB-0023540D61DA dwade        2    6143

uxenapi node에 가입된 PM들의 정보가 모두 나온다.

3.PM State:

# uxencli pm-stat

UUID            : A064D172-E07E-DD11-91FE-0023541104C2
Name            : worthy
Total CPU       : 4
Used CPU        : 5
Hyperthread     : off
CPU Ratio       : 125.0 %
Total Memory    : 8191
Used Memory     : 5119
Running VMs     : 3
Networks        : [ifname] [rx_sum]           [tx_sum]
                  total    12018975514        2552684375
                  xenbr1   4795256568         1047308430
                  xenbr0   301980854          50415042
                  eth0     1747870919         49684202
                  eth1     5173867173         1405276701
Created         : 2019-05-28T06:53:40.070080Z
Updated         : 2019-06-14T00:45:33.758190Z

Backup 관련 기능

1.Backup Add:

# uxencli backup-add f9423a1a-2a51-47b9-be0c-8b1fffa4935c backup_test 21 "backup test"
Success

2.Backup Delete 는 Backup 관련기능 모두 수행후 진행 함:

# uxencli backup-del f9423a1a-2a51-47b9-be0c-8b1fffa4935c 9cc67e6a-26a6-4b14-be49-7ea7b24949f9

Success

백업 이미지 정상적으로 삭제 확인 완료.

3.Backup Disk List:

# uxencli backup-disk-list f9423a1a-2a51-47b9-be0c-8b1fffa4935c 1f8b2a27-b6e3-4516-815c-3fa4e89dd59b

DISK_UUID                            STORLINK SIZE   FORMAT ORDER
50491138-80c0-4c49-adff-10e8d25ac39e 21       30720  qcow2  1

4.Backup List:

# uxencli backup-list f9423a1a-2a51-47b9-be0c-8b1fffa4935c

UUID                                 NAME                     SIZE     CREATED
9cc67e6a-26a6-4b14-be49-7ea7b24949f9 -                        30720    2019-06-27T02:21:55.043980Z
1f8b2a27-b6e3-4516-815c-3fa4e89dd59b -                        30720    2019-06-27T02:15:38.322701Z

5.Backup Restore:

# uxencli backup-restore f9423a1a-2a51-47b9-be0c-8b1fffa4935c 1f8b2a27-b6e3-4516-815c-3fa4e89dd59b

Failure (Bad Request) : {"message":"The VM should be stopped.","result":203}

VM 구동중일땐 불가능 한것으로 보인다. shutdown 이후 시도:

# uxencli backup-restore f9423a1a-2a51-47b9-be0c-8b1fffa4935c 1f8b2a27-b6e3-4516-815c-3fa4e89dd59b

Success

backup-restore 이후 이전 백업 이미지 상태로 되돌아가는 것을 확인.

]]>
Mon, 01 Jul 2019 00:00:00 +0900
http://www.iorchard.net/2019/06/24/aoe_이미지_쓰기_확인.html http://www.iorchard.net/2019/06/24/aoe_이미지_쓰기_확인.html <![CDATA[AOE 이미지 쓰기 확인]]> AOE 이미지 쓰기 확인

[개요]

PengX3 테스트서버 환경 구축중 AOE LVM 볼륨에서 uxencli vm-add 를 진행 하면

fail 이 나타나면서 aoe down 현상이 나타남..

자세한 이해를 돕기 위해 아래에 이미지를 첨부 하겠다.

../../../_images/aoe_sda.jpg

sda로 부터 할당된 xvda AOE 볼륨에 sda GVM을 쓰기 - 실패

[테스트 조건]

../../../_images/aoe_sdb.jpg

sdb로 부터 할당된 xvdb AOE 볼륨에 sda GVM을 쓰기 - 시도 해 보겠다.

AOE VM에 sdb 디스크를 추가 하겠다.

fdisk로 sdb를 파티션 생성

:/home/orchard# fdisk /dev/sdb

Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb4ee30d3



Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-1953525167, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-1953525167, default 1953525167): +300G

Created a new partition 1 of type 'Linux' and of size 300 GiB.

Command (m for help): p
Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb4ee30d3

Device     Boot Start       End   Sectors  Size Id Type
/dev/sdb1        2048 629147647 629145600  300G 83 Linux


Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 83
Changed type of partition 'Linux' to 'Linux'.

Command (m for help): p
Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb4ee30d3

Device     Boot Start       End   Sectors  Size Id Type
/dev/sdb1        2048 629147647 629145600  300G 83 Linux


Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

xfs 로 포맷

:/home/orchard# mkfs.xfs -f /dev/sdb1
meta-data=/dev/sdb1              isize=256    agcount=4, agsize=19660800 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=78643200, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=38400, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

마운트

# mount /dev/sdb1 /data2

sdb1을 storlink에 추가

# uxencli storlink-add worthy_data2 /data2 "data2 sdb1" lo fl false
Success

sdb1 storlink를 aoe VM에 디스크 추가

# uxencli vm-disk-add deaf14fc-f7d6-43d8-8712-218afb8037db 300000 18 "worthy sdb1"
Success

aoe VM에서 aoe 노출 시키겠다.

# vblade 1 0 eth1 /dev/xvdc
pid 591: e1.0, 614400000 sectors O_RDWR

aoe VM에 sdb aoe discover,stat 실행(aoe 볼륨 가져오기)후

fdisk로 partion 진행:

# fdisk /dev/etherd/e1.0

Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x751b3d5d.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-614399999, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-614399999, default 614399999):

Created a new partition 1 of type 'Linux' and of size 293 GiB.

Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 83
Changed type of partition 'Linux' to 'Linux'.

Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

pv,vg create:

# pvcreate /dev/etherd/e1.0p1
Physical volume "/dev/etherd/e1.0p1" successfully created.
# vgcreate aoe_disk2 /dev/etherd/e1.0p1
Volume group "aoe_disk2" successfully created

생성된 vg로 storlink-add:

# uxencli storlink-add aoe-vm2 /dev/aoe_disk2 "aoe vm2" fc bl true
Success

storlink 등록후 vm-add로 sda에 있는 GVM을 sdb 기반으로 생성된 xvdc 디스크 생성은

안되는것으로 확인되었다.

다른PM의 GVM을 vm-add로xvdc aoe볼륨에 디스크 쓰기를 하니 정상.

../../../_images/dwade_aoe.jpg

aoe xvdc(sdb) 에 gvm을 두고 xvdc의aoe 볼륨에 aoe add 해보자.

]]>
Mon, 24 Jun 2019 00:00:00 +0900
http://www.iorchard.net/2019/06/17/efk_stack_구성.html http://www.iorchard.net/2019/06/17/efk_stack_구성.html <![CDATA[EFK Stack 구성]]> EFK Stack 구성

개요

EFK Stack을 구성하여 사내 서버들의 로그를 중앙수집하여 관리하자.

서버 자원이 넉넉하지 않아 여러 클러스터로 구성하지는 못하지만 대량의 로그를 수집하는 것도 아니고 단일노드로 환경에서도 로그수집용 EFK 를 구성할 수 있으니 최대한 장점을 살려 도입하자.

로그서버 스펙

adavis에 가상머신으로 로그 수집용 서버를 만들었다.

서버 유형 Hostname OS CPU 메모리 서비스망 IP 내부망 IP
가상 머신 log-server Debian stretch 4 Cores 8G <secret> <secret> (/24)
  • 위 서버에 Fluent Bit+ Elasticsearch+ Kibana를 구성한다.

Architectre

구성도.:

+----------+--------+------------+
| odom     | syslog | Fluent Bit |---+
+----------+--------+------------+   |
                                     |
                                     |
+----------+--------+------------+   |
| redmine  | syslog | Fluent Bit |---+           +-------------------log-server-----------------+
+----------+--------+------------+   |           |                                              |
                                     |           |                                              |
+----------+--------+------------+   |     +-----+---+     +---------------+     +--------+     |
| lebron   | syslog | Fluent Bit |---+---->| Fluentd |---> | Elasticsearch |---> | Kibana |     |
+----------+--------+------------+   |     +---------+     +---------------+     +--------+     |
                                     |           |                                              |
               *                     |           |                                              |
               *                     |           +----------------------------------------------+
               *                     |
                                     |
+----------+--------+------------+   |
| pvdi     | syslog | Fluent Bit |---+
+----------+--------+------------+
  • 각 서버(odom, redmine, lebron 등) 의 syslog, APP 로그를 Fluent Bit가 수집한다.
  • Fluent Bit가 수집한 로그를 log-server(aggregator)로 보낸다. 이때 fluentd가 중앙에서 모든 로그를 수집하게 된다.
  • Fluentd는 output인 ES로 로그를 저장한다.
  • ES에 저장된 로그 데이터를 Kibana로 시각화한다.

우리 서버 odom, lebron 등이 오래된 버전(Debian Lenny) Fluent Bit를 컴파일해야 한다.

그래서 우선 아래와 같이 rsyslog에 remote 설정하여 syslog만(APP로그 제외) Fluentd에서 수집하도록 구성한다.

(차후 각 서버에 Fluent Bit을 컴파일하여 APP 로그도 수집하도록 구성할 예정)

새롭게 바뀐 구성도.:

+----------+--------+
| odom     | syslog |---+
+----------+--------+   |
                        |
                        |
+----------+--------+   |
| redmine  | syslog |---+           +-------------------log-server-----------------+
+----------+--------+   |           |                                              |
                        |           |                                              |
+----------+--------+   |     +-----+---+     +---------------+     +--------+     |
| lebron   | syslog |---+---->| Fluentd |---> | Elasticsearch |---> | Kibana |     |
+----------+--------+   |     +---------+     +---------------+     +--------+     |
                        |           |                                              |
               *        |           |                                              |
               *        |           +----------------------------------------------+
               *        |
                        |
+----------+--------+   |
| pvdi     | syslog |---+
+----------+--------+

Installation EFK Stack

EFK 를 설치하면서 필수로 구성해야 할 설정들이 있는데, 설정에 대한 설명은 installation EFK 에서 EFK 를 설치하며 알아보았으니 여기선 생략한다.

1.) Flentd 설치

Fluentd 설치.:

root@log-server:~# curl -L https://toolbelt.treasuredata.com/sh/install-debian-stretch-td-agent3.sh | sh

상태 확인.:

root@log-server:~# systemctl status td-agent
● td-agent.service - td-agent: Fluentd based data collector for Treasure Data
   Loaded: loaded (/lib/systemd/system/td-agent.service; disabled; vendor preset: enabled)
   Active: active (running) since Wed 2019-06-12 17:38:21 KST; 5min ago
     Docs: https://docs.treasuredata.com/articles/td-agent
  Process: 3358 ExecStart=/opt/td-agent/embedded/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/
 Main PID: 3363 (fluentd)
    Tasks: 11 (limit: 4915)
   CGroup: /system.slice/td-agent.service
           ├─3363 /opt/td-agent/embedded/bin/ruby /opt/td-agent/embedded/bin/fluentd --log /var/log/td-agent/td-agen
           └─3368 /opt/td-agent/embedded/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/embedded/bin/fluentd --log /

 6월 12 17:38:20 log-server systemd[1]: Starting td-agent: Fluentd based data collector for Treasure Data...
 6월 12 17:38:21 log-server systemd[1]: Started td-agent: Fluentd based data collector for Treasure Data.

NTP 설정.:

root@log-server:~# apt install ntp

File Descriptor 설정.:

root@log-server:~# ulimit -n
1024
root@log-server:~# tail /etc/security/limits.conf
...
root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536

root@log-server:~# reboot
  • 적용하려면 reboot이 필요하다.
  • 할당할 수 있는 파일디스크립터의 개수가 1024인데, 이것을 65536으로 늘렸다.

Optimize Network Kernel Parameters.:

root@log-server:~# tail -n 15 /etc/sysctl.conf
...
net.core.somaxconn = 1024
net.core.netdev_max_backlog = 5000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.ipv4.tcp_rmem = 4096 12582912 16777216
net.ipv4.tcp_max_syn_backlog = 8096
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10240 65535

root@log-server:~# sysctl -p

서비스 자동시작.:

root@log-server:~# systemctl enable td-agent-bit

td-agent v3.4.0 설치 완료!

2.) Elasticsearch 설치

PGP Key 가져오기.:

root@log-server:~# wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
OK

source list 추가.:

root@log-server:~# echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list
deb https://artifacts.elastic.co/packages/7.x/apt stable main

elasticsearch 설치.:

root@log-server:~# apt update && apt install elasticsearch

서비스 자동시작.:

root@log-server:~# systemctl enable elasticsearch

elasticsearch 유저의 최대 파일 디스크립터 설정.:

root@log-server:~# vi /usr/lib/systemd/system/elasticsearch.service
...
LimitNOFILE=65535

elasticsearch가 스왑메모리를 사용하지 않도록 설정.:

root@log-server:~# cat /etc/elasticsearch/elasticsearch.yml
...
bootstrap.memory_lock: true

root@log-server:~# ulimit -l unlimited

root@log-server:~# tail /usr/lib/systemd/system/elasticsearch.service
...
[Service]
LimitMEMLOCK=infinity
...

root@log-server:~# systemctl daemon-reload
root@log-server:~# systemctl restart elasticsearch

root@log-server:~# curl -X GET localhost:9200/_nodes?filter_path=**.mlockall
{"nodes":{"sAQ9SlscTP2vn5ALyqgIAQ":{"process":{"mlockall":true}}}}
  • mlockall”:true 로 나와야 한다.

Elasticsearch는 기본적으로 index를 저장하기 위해 mmapfs 디렉토리를 사용하는데, mmap 카운트의 기본값이 너무 낮아 메모리 부족 예외가 발생할 수 있다.

그래서 아래와 같이 값을 늘린다.:

root@log-server:~# cat /usr/lib/sysctl.d/elasticsearch.conf
vm.max_map_count=262144

root@log-server:~# sysctl -p

Java Heap 메모리 설정.:

root@log-server:~# grep Xm /etc/elasticsearch/jvm.options
-Xms4g
-Xmx4g
  • log-server의 총 메모리가 8G인데, 절반을 Java Heap으로 설정하는 것을 권장한다.
  • 나머지 절반은 루씬 파일 캐시를 위해 남겨두어야 한다.

cluster 이름 설정.:

root@log-server:~# cat /etc/elasticsearch/elasticsearch.yml |grep cluster.name
cluster.name: orchard-cluster

root@log-server:~# curl -X GET http://localhost:9200/
{
  "name" : "log-server",
  "cluster_name" : "orchard-cluster",
  "cluster_uuid" : "_kcvsCznTkmEa-l997rQRQ",
  "version" : {
    "number" : "7.1.1",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "7a013de",
    "build_date" : "2019-05-23T14:04:00.380842Z",
    "build_snapshot" : false,
    "lucene_version" : "8.0.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
  • Elasticsearch v 7.1.1 설치 완료!

Elasticsearch를 설치하면 x-pack이 함께 설치된다.

x-pack을 간단하게 소개하자면 보안, alert, monitoring, reporting, graph 관련 기능을 하나로 모아 놓은 패키지 플러그인이다.

3.) Kibana 설치

GPG Key 가져오기.:

root@log-server:~# wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
OK

source list 추가.:

root@log-server:~# echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list
deb https://artifacts.elastic.co/packages/7.x/apt stable main

Kibana 설치.:

root@log-server:~# apt update && apt install kibana

root@log-server:~# systemctl enable kibana

네트워크 설정.:

root@log-server:~# grep server.host /etc/kibana/kibana.yml
server.host: "0.0.0.0"

root@log-server:~# systemctl restart kibana
  • Kibana 7.1.1 설치 완료!

fluentd 구성

Fluentd에서 syslog를 수신받아 ES에 저장하도록 구성하자.:

root@log-server:~# cat /etc/td-agent/td-agent.conf
<source>
  @type syslog             # parsing for syslog
  port 5140                # UDP 5140 port liten
  bind log-server          # Internal IP
  tag syslog
</source>

<match syslog.**>
  @type copy
  <store>
    @type stdout
  </store>
  <store>
    @type elasticsearch
    host 127.0.0.1
    port 9200
    logstash_format true                         # 이렇게 하면 ES에 로그를 저장할 수 있고, Kibana를 이용할 수 있다. (default : flase)
    logstash_prefix fluentd-syslog               # Set index name (default : fluentd)
    logstash_dateformat %Y%m%d                   # index name-{dateformat} ex) fluentd-syslog-20190613
    include_tag_key true                         # Include tag key (logname)
    tag_key @logname                             # Include logname

    buffer_type file                             # chunk wirte at file (default: memory)
    buffer_path /var/log/td-agent/buffer/syslog/ # chunk path
    flush_interval 1s                            # chunk가 queue로 이동하도록 flush 하는 간격 (아래 chunk limit 값이 다 되거나 이 interval 간격에 의해 데이터가 queue로 이동된다.)
    buffer_chunk_limit 256m                      # 각 청크의 최대 크기를 나타냄. limit 값이 될 때까지 이벤트가 청크에 기록되고 limit 값이 되면 queue로 데이터가 이동된다. (ddefault : mem-8M / file-256M)
    buffer_queue_limit 256                       # chunk는 output으로 이동하기 전에 queue에서 대기하는데 이 큐에 쌓일 수 있는 청크의 개수를 의미한다. (default : 256)
    retry_wait 5                                 # queue에 쌓인 chunk를 output으로 보내는데, 만약 도착지에 문제가 있어 데이터를 쓰지 못하면 retry_wait 간격만큼 대기 후 다시 시도한다. 또 실패하면 2대 만큼 기다린다. (5s, 10s, 20s, 40s ...)
    buffer_queue_full_action drop_oldest_chunk   # queue가 가득 차버렸을 때 처리에 대한 정책인데, 이 정책은 가장 오래된 청크를 삭제한다.
  </store>
</match>

위 설정을 설명하자면 우선 <source> 섹션에서는 syslog를 받아오기 위한 설정이다.

  • @type syslog : syslog input 플러그인인데, syslog를 파싱해서 JSON 형태로 로그를 가공해준다.
  • port 5140 : syslog를 받아올 port를 지정하는 것인데, udp 5140 포트를 listen하여 5140포트로 들어오는 로그를 모두 수집한다.
  • bind : bind address를 입력하는 것인데, 해당 서버의 internal IP로 바인딩하였다. /etc/hosts에 log-server의 정의가 있기 때문에 hostname으로 입력함.
  • tag : tag는 임의의 값으로 해당 input을 식별하기 위한 식별자 인데, 아래 <match syslog.**>에서 해당 input을 식별하여 output으로 보낸다.

<match> 섹션은 input을 output으로 보내기 위한 설정이다.

  • @type copy : <store> output을 보낼 저장소로 카피해서 보내기 위해 설정했다. stdout은 디버깅용이라 차후에는 삭제할 것이다.
  • <store> @type stdout : output을 지정하는 섹션인데, @type stdout은 터미널로 output을 출력한다. 디버깅용으로 사용.
  • <store> @type elasticsearch : 수집한 로그를 ES로 보내기 위한 설정이다.
  • host : ES 서버의 IP를 지정하는 설정인데, 여기선 fluentd와 ES가 하나의 서버에서 구동되어 127.0.0.1을 입력하였다.
  • port : ES 서버의 port를 입력하는 설정이다.
  • logstash_format true : 이렇게 하면 ES에 로그를 저장할 수 있고, Kibana를 이용할 수 있다. 기본값은 false이다.
  • logstash_prefix fluentd-syslog : ES에 생성될 index 이름을 정의하는 설정이다.
  • logstash_dateformat %Y%m%d : index 이름 뒤에 지정될 날짜 형식을 지정하는 설정이다.
  • include_tag_key : 이렇게하면 tag가 json 레코드의 value로 추가되는데 아래 tag_key의 이름이 key가 된다. ex) {“@logname”: “syslog”}
  • buffer_type file : output으로 데이터를 보내기 전에 chunk 단위로 데이터를 버퍼하는데, 버퍼를 메모리가 아닌 file로 하겠다는 설정이다.
  • buffer_path : buffer가 저장될 경로.
  • flush_interval : buffer된 데이터가 output으로 보내는 간격.
  • buffer_chunk_limit : buffer 사이즈를 정하는 설정인데, 이 사이즈가 full되면 output으로 flush 된다. chunk 사이즈가 full 되지 않아도 위 flush_interval 시간이 되면 chunk에 쌓인 로그가 output으로 flush 된다.
  • buffer_queue_limit : chunk는 output으로 이동하기 전에 queue에서 대기하게 되는데, 이때 queue에 쌓일 수 있는 청크의 개수를 의미한다.
  • retry_wait : queue에 쌓인 chunk를 output으로 보내는데, 만약 도착지에 문제가 있어 데이터를 쓰지 못하면 retry_wait 간격만큼 대기 후 다시 시도한다. 또 실패하면 2대 만큼 기다린다. (5s, 10s, 20s, 40s …)
  • buffer_queue_full_action : 만약 queue에 있는 데이터가 output으로 보내지지 못하고 큐가 가득 차면 어떻게 처리해야 할지 정책을 설정하는 것인데, drop_oldest_chunk은 가장 오래된 청크를 삭제한다.

이제 fluentd가 5140 포트를 열고 로그를 수신할 준비가 되었다.

우선 작동 확인을 위해 flush_interval을 1초로 두었지만, 작동 확인이 되면 1시간으로 변경할 것이다.

Syslog to Fluentd

syslog를 fluentd(aggregator)로 전송하도록 설정하자.

내가 로그를 수집할 서버는 총 21대 이며, 21대 모두 아래와 같이 동일하게 설정한다.:

root@log-client:~# cat /etc/rsyslog.d/remote.conf
*.* @log-server:5140
  • log-server : Internal IP

rsyslog restart.:

root@log-client:~# systemctl restart rsyslog

syslog를 기록하여 fluentd에 이벤트를 발생시키자.:

root@log-client:~# logger 하이루

log-server에서 확인한다.:

root@log-server:~# tail -f /var/log/td-agent/td-agent.log
...
2019-06-14 17:22:29.000000000 +0900 syslog.user.notice: {"host":"log-client","ident":"orchard","message":"하이루"}
  • Fluentd가 로그를 잘 수신했다.
  • Fluentd가 INPUT을 잘 수신하는 것을 검증했으니, 이제 OUTPUT으로 잘 내보내지는지 확인하자.

OUTPUT인 Elasticsearch에 로그가 잘 저장되었다면 OUTPUT으로 잘 보내진 것이다.

먼저 index를 조회하였다.:

root@log-server:~# curl -XGET http://localhost:9200/_cat/indices?v
...
health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   fluentd-syslog-20190614         wY-06fX_RomprMkcecxowQ   1   1         64            0     32.4kb         32.4kb
  • 아래 fluentd 설정에 의해 fluentd-syslog-20190614 형식의 index가 생성되었다.
    • fluentd 설정(logstash_prefix fluentd-syslog ,logstash_dateformat %Y%m%d)
  • health가 yellow인데, 이는 단일 노드라 replica를 저장할 노드가 없어서 그렇다.
    • Index의 상태에 대한 설명 참조 : https://brunch.co.kr/@alden/43
    • 만약 replica를 0으로 바꾸면 상태는 green이 될것이다. 기본값은 shard5, replia 1이다.
    • index 상태 및 설정 변경은 아래 진행하면서 자세히 다루기로 한다.

위 인덱스를 Kibana 에서 확인할 수 있도록 Kibana 대시보드에 접속하여 아래와 같이 인덱스 패턴을 만들자.

  • Management 클릭
  • Create index pattern 클릭
  • fluentd-syslog* 입력 (fluentd로 부터 수집하여 ES에 저장한 인덱스)
  • Next step 클릭
  • Time Filter field name : @timestamp 입력
  • Create index pattern 클릭

이제 Discover 탭으로 이동하여 수집된 로그를 확인할 수 있고 하이루로그가 잘 보인다.

ES에 쿼리를 날려 확인해보면 데이터 형식이 아래와 같다.:

root@log-server:~# curl -XGET http://localhost:9200/fluentd-syslog-20190614/_doc/G0QUVWsBAYTatQjE4KEr?pretty
{
  "_index" : "fluentd-syslog-20190614",
  "_type" : "_doc",
  "_id" : "G0QUVWsBAYTatQjE4KEr",
  "_version" : 1,
  "_seq_no" : 63,
  "_primary_term" : 2,
  "found" : true,
  "_source" : {
    "host" : "log-client",
    "ident" : "orchard",
    "message" : "하이루",
    "@timestamp" : "2019-06-14T17:22:29.000000000+09:00",
    "@logname" : "syslog.user.notice"
  }
}

Index Template

Index Template는 인덱스가 사용할 mapping, setting을 미리 저장해두고 인덱스가 자동으로 생성될 때 해당 mapping, setting을 적용하기 위해 사용된다.

에를들어, 나의 경우 아래와 같이 인덱스가 하루에 한번씩 자동으로 생성된다.

  • fluentd-syslog-20190614
  • fluentd-syslog-20190615
  • fluentd-syslog-20190616
  • fluentd-syslog-20190617

이때 위 모든 인덱스의 설정이 shard: 5, replica: 1 이라 index health가 yellow상태이다.

만약, fluentd-syslog-20190614 인덱스의 설정을 shard5, replica0 으로 설정하여 상태를 green으로 바꾸어도 다음날 자동으로 생성되는 fluentd-syslog-20190615 인덱스는 또 다시 shard5, replica1 로 설정되어 Yellow 상태로 보인다.

이러한 이유로 인해 shard1, replica0 으로 설정된 index template를 만들어 fluentd-syslog* 와 같은 패턴을 조건으로 생성되는 인덱스에 적용하도록 설정하자.

shard 1, replica 0 으로 설정한 이유는 단일 노드로 운영할 것이기 때문에 shard와 replica를 분산하여 저장할 다른 노드가 없기 때문이다.

shard와 relica의 설명은 아래 링크를 참조하자.

먼저 템플릿을 만든다.:

root@log-server:~# curl -XPUT http://localhost:9200/_template/fluentd-syslog-temp -H 'Content-Type: application/json' -d'
 {
 "index_patterns": [
     "fluentd-syslog*"
 ],
 "settings": {
     "number_of_shards": 1,
     "number_of_replicas" : 0
 }}'

템플릿 확인.:

root@log-server:~# curl -XGET http://localhost:9200/_template/fluentd-syslog-temp?pretty
{
  "fluentd-syslog-temp" : {
    "order" : 0,
    "index_patterns" : [
      "fluentd-syslog*"
    ],
    "settings" : {
      "index" : {
        "number_of_shards" : "1",
        "number_of_replicas" : "0"
      }
    },
    "mappings" : { },
    "aliases" : { }
  }
}
  • 이제 fluentd-syslog* 패턴으로 만들어지는 인덱스는 shard1, replica0 으로 생성될 것이다.

검증을 위해 fluentd-syslog* 의 모든 인덱스를 삭제하자.:

root@log-server:~# curl -XDELETE http://localhost:9200/fluentd-syslog-20190614?pretty
{
  "acknowledged" : true
}
root@log-server:~# curl -XDELETE http://localhost:9200/fluentd-syslog-20190615?pretty
{
  "acknowledged" : true
}
root@log-server:~# curl -XDELETE http://localhost:9200/fluentd-syslog-20190616?pretty
{
  "acknowledged" : true
}
root@log-server:~# curl -XDELETE http://localhost:9200/fluentd-syslog-20190617?pretty
{
  "acknowledged" : true
}
  • 14일 ~ 17일 동안 자동으로 생성된 fluent-syslog를 모두 삭제하였다.

이제 이벤트를 발생시켜 새로운 인덱스를 만들고 shard, replica 설정을 확인하자.

먼저 log-client에서 로그를 발생시켰다.:

orchard@log-client:~$ logger 하이루2

이후 log-server에서 index를 확인했다.:

root@log-server:~# curl -XGET http://localhost:9200/_cat/indices?v
health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   fluentd-syslog-20190617         VwAc5IJ_Sm287h265WS10w   1   0          1            0       171b           171b
...
  • 새로운 인덱스(fluentd-syslog-20190617) 가 생성되었고, health를 보니 green임을 확인했다.

정확하게 index setting 정보를 확인해보자.:

root@log-server:~# curl -XGET http://localhost:9200/fluentd-syslog-20190617/_settings/?pretty
{
  "fluentd-syslog-20190617" : {
    "settings" : {
      "index" : {
        "creation_date" : "1560745247119",
        "number_of_shards" : "1",
        "number_of_replicas" : "0",
        "uuid" : "VwAc5IJ_Sm287h265WS10w",
        "version" : {
          "created" : "7010199"
        },
        "provided_name" : "fluentd-syslog-20190617"
      }
    }
  }
}
  • shard : 1
  • replica : 0
  • 템플릿이 잘 적용된 것을 확인했다.

Index Lifecycle

index lifecycle management(ILM)은 시간이 지남에 따라 인덱스를 관리하는 방법을 자동화한다.

예를들어, 로그 데이터를 무한정 저장하지 않고 생명주기 정책을 설정하여 90동안만 보관하고 90일이 지난 로그 데이터는 롤 오버하거나 shard를 줄이거나 다른 서버로 인덱스를 보내거나 삭제하거나 하는 개념이다.

인덱스 생명주기 단계에는 4단계가 있다.

단일 노드 환경에서는 delete 정책 정도 반영할 수 있을 것 같다.

나의 경우 90일이 지난 로그는 삭제하도록 설정할 것이다.

인덱스 생명주기 정책을 만들자.:

root@log-server:~# curl -XPUT http://localhost:9200/_ilm/policy/fluentd-syslog-ilm -H 'Content-Type: application/json' -d'
 {
     "policy": {
         "phases": {
             "hot": {
                 "min_age": "0ms",
                 "actions": {
                     "set_priority": {
                         "priority": 0
                     }
                 }
             },
             "delete": {
                 "min_age": "90d",
                 "actions": {
                     "delete": {}
                 }
             }
         }
     }
 }'
  • hot 단계는 필수로 활성화 시켜야 한다.
  • delete 단계를 넣어주었고, min_age : 90d 로 주었다.
  • 그럼 90일 동안 index를 보관하고 90일이 지난 인덱스는 자동으로 삭제된다.

생명주기 정책을 인덱스에 적용하려면 인덱스 템플릿이 필요한데, 특정 인텍스 템플릿에 적용하여 인덱스 템플릿과 일치하는 모든 인덱스에 생명주기 정책이 부여된다.

그렇다면 위에서 만든 인덱스 생명주기 정책(fluentd-syslog-ilm)을 인덱스 템플릿(fluentd-syslog-temp) 에 적용하자. Kibana 대시보드에 접속하여 아래와 같이 설정하였다.

  • management 탭 클릭
  • Index Lifecycle Policies 클릭
  • fluentd-syslog-ilm 라인의 Actions 클릭
  • Add policy to index template 클릭
  • fluentd-syslog-temp 선택 -> Add policy

검증을 위해 다시 Index를 지우자.:

root@log-server:~# curl -XDELETE http://localhost:9200/fluentd-syslog-20190617?pretty

로그를 새롭게 생성한다.:

orchard@log-client:~$ logger 하이루23

Index의 설정을 확인한다.:

root@log-server:~# curl -XGET http://localhost:9200/fluentd-syslog-20190617/_settings/?pretty
{
  "fluentd-syslog-20190617" : {
    "settings" : {
      "index" : {
        "lifecycle" : {
          "name" : "fluentd-syslog-ilm"
        },
        "number_of_shards" : "1",
        "provided_name" : "fluentd-syslog-20190617",
        "creation_date" : "1560753820382",
        "priority" : "0",
        "number_of_replicas" : "0",
        "uuid" : "a70z4QePRG6h5k9Kyu8rvQ",
        "version" : {
          "created" : "7010199"
        }
      }
    }
  }
}
  • 이 인덱스에 “lifecycle” : { “name” : “fluentd-syslog-ilm” } 정책이 반영된 것을 확인했다.

인증 적용하기

Kibana 대시보드에 인증을 적용할 필요를 느꼈다. 누구든 접속할 수 있으니 보안상 좋지 않다.

ES를 설치하면서 x-pack이 같이 설치되었는데, x-pack은 보안, alert, 모니터링, 리포팅 등 관련 기능을 모아놓은 패키지 플러그인인데 몇가지는 유료이고 몇가지는 무료이다.

ES 라이센스 정책에 따라 사용할 수 있는 기능이 제한되는데 opensource, basic, gold, platinum
총 4가지로 나뉘고 각 등급에 따라 사용할 수 있는 기능이 나뉜다.

원래는 x-pack 전체가 라이센스가 필요했으나 6.3 버전부터 오픈소스로 변경되었고 basic은 라이센스 등록 없이 무료로 사용가능하다.

자세한 ES 라이센스 정책은 아래 링크를 참조하자.

Stack Monitoring도 basic이라 무료로 사용할 수 있는데, Kibana 대시보드에 접속하여 Stack Monitoring 탭을 클릭하고 활성화하면 된다.

그럼 Kibana와 ES의 Node상태, CPU, MEM, index, disk, documents등 다양한 자원을 모니터링 할 수 있다.

security는 기본인증은 basic으로 무료로 사요할 수 있고 LDAP, SSO등은 gold, platinum이라 라이센스가 필요하다.

basic 라이센스인 기본인증을 적용하자.

ES 설정

먼저 ES의 설정파일을 수정하자.:

root@log-server:~# tail -n1 /etc/elasticsearch/elasticsearch.yml
xpack.security.enabled: true

root@log-server:~# systemctl restart elasticsearch
  • ES 7.1은 기본으로 False인데, 이것을 true로 변경하였다.

ES에는 기본으로 제공하는 6가지의 유저가 존재한다.

  • elastic : A built-in superuser. See Built-in roles.
  • kibana :The user Kibana uses to connect and communicate with Elasticsearch.
  • logstash_system : The user Logstash uses when storing monitoring information in Elasticsearch.
  • beats_system : The user the Beats use when storing monitoring information in Elasticsearch.
  • apm_system : The user the APM server uses when storing monitoring information in Elasticsearch.
  • remote_monitoring_user : The user Metricbeat uses when collecting and storing monitoring information in Elasticsearch. It has the remote_monitoring_agent and remote_monitoring_collector built-in roles.
  • 참조 : https://www.elastic.co/guide/en/elastic-stack-overview/current/built-in-users.html#built-in-user-explanation

위 기본 유저의 암호를 설정한다.:

root@log-server:~# /usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive

Failed to determine the health of the cluster running at http://127.0.0.1:9200
Unexpected response code [503] from calling GET http://127.0.0.1:9200/_cluster/health?pretty
Cause: master_not_discovered_exception

It is recommended that you resolve the issues with your cluster before running elasticsearch-setup-passwords.
It is very likely that the password changes will fail when run against an unhealthy cluster.

Do you want to continue with the password setup process [y/N]y

Initiating the setup of passwords for reserved users elastic,apm_system,kibana,logstash_system,beats_system,remote_monitoring_user.
You will be prompted to enter passwords as the process progresses.
Please confirm that you would like to continue [y/N]y


Enter password for [elastic]:
Reenter password for [elastic]:
Enter password for [apm_system]:
Reenter password for [apm_system]:
Enter password for [kibana]:
Reenter password for [kibana]:
Enter password for [logstash_system]:
Reenter password for [logstash_system]:
Enter password for [beats_system]:
Reenter password for [beats_system]:
Enter password for [remote_monitoring_user]:
Reenter password for [remote_monitoring_user]:

Unexpected response code [503] from calling PUT http://127.0.0.1:9200/_security/user/apm_system/_password?pretty
Cause: Cluster state has not been recovered yet, cannot write to the security index

Possible next steps:
* Try running this tool again.
* Try running with the --verbose parameter for additional messages.
* Check the elasticsearch logs for additional error details.
* Use the change password API manually.

ERROR: Failed to set password for user [apm_system].
  • 에러가 발생한다. 왜?..
  • 해결책은 평가판 라이센스를 활성화 후 재시도 하는 것이었다.
  • 기본인증은 basic 라이센스도 사용할 수 있지만, security 기능을 사용하려면 평가판 라이센스를 무조건 한번은 켜야하는건가…?

나는 basic 라이센스(기본 free license)를 가지고 있는데, 이 라이센스를 아래와 같이 Platinum으로 올렸다.

우선 elasticsearch를 stop한다.:

root@log-server:~# systemctl stop elasticsearch

x-pack security 설정을 끄고 다시 시작한다:

root@log-server:~# vi /etc/elasticsearch/elasticsearch.yml
...
#xpack.security.enabled : true

root@log-server:~# systemctl start elasticsearch

다음으로 Kibana 대시보드에 접속하여 30일 평가판 라이센스를 활성화한다.

  • Kibana 대시보드 접속
  • Management 탭 클릭
  • 평가판 라이센스 활성화

이후 아래와 같이 다시 x-pack security를 켰다.:

root@log-server:~# vi /etc/elasticsearch/elasticsearch.yml
...
xpack.security.enabled : true

root@log-server:~# systemctl restart elasticsearch

이제 다시 ES 필수 계정들의 암호를 설정했다.:

root@log-server:~# /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto
Initiating the setup of passwords for reserved users elastic,apm_system,kibana,logstash_system,beats_system,remote_monitoring_user.
The passwords will be randomly generated and printed to the console.
Please confirm that you would like to continue [y/N]y


Changed password for user apm_system
PASSWORD apm_system = <PASSWD>

Changed password for user kibana
PASSWORD kibana = <PASSWD>

Changed password for user logstash_system
PASSWORD logstash_system = <PASSWD>

Changed password for user beats_system
PASSWORD beats_system = <PASSWD>

Changed password for user remote_monitoring_user
PASSWORD remote_monitoring_user = <PASSWD>

Changed password for user elastic
PASSWORD elastic = <PASSWD>
  • elasticsearch-setup-passwords 명령의 인자로 auto와 interactive를 넣을 수 있는데,
  • auto는 자동으로 랜덤하게 암호를 설정해주고,
  • interactive는 사용자가 직접 암호를 설정하는 것이다.
  • 나의 경우 auto라서 암호는 <PASSWD>로 표시했다.

Fluentd 설정

ES에서 security 기능을 켰으니 Fluentd가 로그 데이터를 ES에 저장할 수 있도록 인증을 해야한다.

ES는 RBAC 이므로 먼저 Role을 만들고, Fluentd 유저를 만든 뒤 해당 Role을 Fluentd에게 Role을 부여할 것이다.

fluentd는 index template를 관리하고 index와 document를 만들고 삭제할 권한이 필요하다.

Role을 만들 때 아래 2가지로 권한이 나뉜다.

logstach 에서 로그를 저장하기 위해 사용하는 role을 그대로 fluentd에 적용하려 한다.

아래와 같은 권한이 필요하다.

  • cluster privileges : manage_index_template, monitor
  • index privileges : write, delete, create_index

만약 인덱스 생명주기 관리(ILM)을 사용하는 경우 추가로 아래 권한이 필요

(나의 경우 ILM을 사용하니 추가로 아래 권한도 넣어 role을 만들 것이다.

  • cluster privileges : manage_ilm
  • index privileges : manage, manage_ilm

fluentd writer라는 이름으로 role을 만들자.:

root@log-server:~# curl -XPUT -u elastic http://localhost:9200/_xpack/security/role/fluentd_writer -H 'Content-Type: application/json' -d'
{
  "cluster": ["manage_index_templates", "monitor", "manage_ilm"],
  "indices": [
    {
      "names": [ "fluentd-syslog*" ],
      "privileges": ["write","delete","create_index","manage","manage_ilm"]
    }
  ]
}'

Enter host password for user 'elastic':
{"role":{"created":true}}

fluentd라는 유저를 만들고 fluentd_writer role을 부여한다.:

root@log-server:~# curl -XPUT -u elastic http://localhost:9200/_xpack/security/user/fluentd -H 'Content-Type: application/json' -d'
{
  "password" : "<PASSWD>",
  "roles" : [ "fluentd_writer"],
  "full_name" : "Fluentd User"
 }'

Enter host password for user 'elastic':
{"created":true}
  • 암호는 <PASSWD>로 따로 표시했다.

이제 fluentd 유저의 권한으로 ES에 로그를 저장할 수 있다.

fluentd 설정파일에 fluentd 유저의 인증 정보를 넣어준다.:

root@log-server:~# cat /etc/td-agent/td-agent.conf
<source>
  @type syslog
  port 5140
  bind log-server
  tag syslog
</source>

<match syslog.**>
  @type copy
  <store>
    @type stdout
  </store>
  <store>
    @type elasticsearch
    host 127.0.0.1
    port 9200
    user fluentd           <<<<추가
    password <PASSWD>      <<<<추가
    ...
  • <store> 섹션에 user와 password를 넣어준다.
  • 패스워드 plain text로 넣기 싫은데, 방법이 없나..

최종 설정은 아래와 같다.:

root@log-server:/var/log/td-agent/buffer/syslog# cat /etc/td-agent/td-agent.conf
<source>
  @type syslog
  port 5140
  bind log-server
  tag syslog
</source>

<match syslog.**>
  @type elasticsearch
  host 127.0.0.1
  port 9200
  user fluentd
  password <PASSWD>

  logstash_format true
  logstash_prefix fluentd-syslog
  logstash_dateformat %Y%m%d
  include_tag_key true
  tag_key @logname

  buffer_type file
  buffer_path /var/log/td-agent/buffer/syslog/
  flush_interval 1h
  buffer_chunk_limit 256m
  buffer_queue_limit 256
  retry_wait 5
  buffer_queue_full_action drop_oldest_chunk
</match>
  • 디버깅용으로 넣어두었던 stdout을 빼고, flush_interval 간격을 1h로 바꾸었다.
  • 이제 Fluentd는 fluentd유저로 인증을 거쳐 ES에 로그를 저장하게 된다.

fluentd를 재시작한다.:

root@log-server:~# systemctl restart td-agent
  • ES에 로그가 잘 저장된다.

kibana 설정

kibana 계정으로 ES의 DB에 엑세스하는데 위에서 변경한 kibana유저의 암호를 kibana에게 알려주어야 한다.

kibana.yml 파일에 ES의 계정과 암호를 넣어주어도 된다.

하지만 보안상 plain text로 넣어주는 것은 안좋으니 kibana-keystore를 사용하기로 했다.

먼저 아래와 같이 key-store를 만든다.:

root@log-server:~# sudo -u kibana /usr/share/kibana/bin/kibana-keystore create
Created Kibana keystore in /var/lib/kibana/kibana.keystore

ES에 엑세스할 kibana유저와 암호를 key-store에 넣어준다.:

root@log-server:~# sudo -u kibana /usr/share/kibana/bin/kibana-keystore add elasticsearch.username
Enter value for elasticsearch.username: ******

root@log-server:~# sudo -u kibana /usr/share/kibana/bin/kibana-keystore add elasticsearch.password
Enter value for elasticsearch.password: ********************
  • elasticsearch.username에 kibana를 넣었고,
  • elasticsearch.password에 kibana계정의 패스워드를 넣었다.
  • 이제 Kibana를 재시작하고나면 Kibana는 keystore의 정보로 ES에 엑세스 할 수 있다.

kibana를 재시작하고 웹브라우저를 열고 kibana 대시보드로 접속하자.

root@log-server:~# systemctl restart kibana
  • 이제 인증을 위한 로그인 화면이 나오고 admin 계정인 elasic으로 로그인이 잘 된다.
  • 난 elastic 유저를 사용하지 않으려고, orchard 계정을 만들어 superuser의 권한을 주었다.

이제 신나게 로그를 수집하고 시각화하자. EFK 구성 완료!

아 마지막으로 80 port to 5601 port 으로 REDIRECT 설정하였다.:

root@log-server:/etc/td-agent# vi /etc/sysctl.conf
net.ipv4.ip_forward=1

root@log-server:~# sysctl -p

root@log-server:~# iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 5601

root@log-server:~# cat /etc/network/interfaces
auto ens8
iface ens8 inet static
        address <secret>
        gateway <secret>
        post-up iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 5601
...
  • post-up 은 해당 인터페이스가 up 되고 난 후 커맨드가 수행된다.
]]>
Mon, 17 Jun 2019 00:00:00 +0900
http://www.iorchard.net/2019/06/10/installation_efk.html http://www.iorchard.net/2019/06/10/installation_efk.html <![CDATA[installation EFK]]> installation EFK

개요

EFK 조합을 구성하여 작동 방식을 알아보자.

  • E : Elastic search
  • F : Fluentd
  • K : kibana

Fluentd?

Fluentd란 오픈소스 데이터 수집기이다.

Fluentd는 유연성을 위해 Ruby로 작성되었으며, 성능에 민감한 부분은 C로 작성되었다.

Fluentd 프로젝트는 Treasure Data 에서 후원한다. 참 감사하다.

라이센스는 아파치 라이선스 2.0 이다.

Fluentd를 이용한 로그 수집 아키텍쳐와 내부 구조는 아래 링크를 참조하여 이해했다.

Before Installation

시험환경

  • OS : CentOS 7.5
  • Hostname : jgs-fluentd

Set Up NTP

NTP(ntpd, chrony) 를 설정하여 정확한 현재 time stamp를 설정해야 하는 것을 권장한다.

ntp를 설치한다.:

[root@jgs-fluentd ~]# yum install ntp

File Descriptor

File Descriptor를 최대 수로 늘려야 한다.

아래 명령으로 현재 file descriptor를 확인한다.:

[root@jgs-fluentd ~]# ulimit -n
1024
  • 1024는 충분하지 않다.

아래 파일에 다음 줄을 추가한다.:

[root@jgs-fluentd ~]# vi /etc/security/limits.conf
...
root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536
  • 적용하려면 서버를 재시작 해야한다.

Optimize Network Kernel Parameters

많은 Fluentd 인스턴스로 구성된 대규모 환경의 경우 아래 매개변수를 추가한다.:

[root@jgs-fluentd ~]# cat /etc/sysctl.conf
...
net.core.somaxconn = 1024
net.core.netdev_max_backlog = 5000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.ipv4.tcp_rmem = 4096 12582912 16777216
net.ipv4.tcp_max_syn_backlog = 8096
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10240 65535

Install by RPM Package

Fluentd 배포 rpm 패키지는 td-agent 이다.

이 패키지는 Treasure Data 에서 관리한다.

td-agent를 설치하자.:

[root@jgs-fluentd ~]# curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh
...
========================================================================================================================================================================
 Package                                           Arch                          Version                                      Repository                           Size
========================================================================================================================================================================
Installing:
 td-agent                                          x86_64                        3.4.1-0.el7                                  treasuredata                         48 M
Installing for dependencies:
 at                                                x86_64                        3.1.13-24.el7                                base                                 51 k
 avahi-libs                                        x86_64                        0.6.31-19.el7                                base                                 61 k
 bc                                                x86_64                        1.06.95-13.el7                               base                                115 k
 cups-client                                       x86_64                        1:1.6.3-35.el7                               base                                151 k
 cups-libs                                         x86_64                        1:1.6.3-35.el7                               base                                357 k
 ed                                                x86_64                        1.9-4.el7                                    base                                 72 k
 m4                                                x86_64                        1.4.16-10.el7                                base                                256 k
 mailx                                             x86_64                        12.5-19.el7                                  base                                245 k
 patch                                             x86_64                        2.7.1-10.el7_5                               base                                110 k
 psmisc                                            x86_64                        22.20-15.el7                                 base                                141 k
 redhat-lsb-core                                   x86_64                        4.1-27.el7.centos.1                          base                                 38 k
 redhat-lsb-submod-security                        x86_64                        4.1-27.el7.centos.1                          base                                 15 k
 spax                                              x86_64                        1.5.2-13.el7                                 base                                260 k
 time                                              x86_64                        1.7-45.el7                                   base                                 30 k

Transaction Summary
========================================================================================================================================================================
Install  1 Package (+14 Dependent packages)
  • 위 쉘 스크립트는 새로운 rpm 저장소를 등록하고 rpm 패키지를 설치한다.

아래와 같이 repo가 추가 된다.:

[root@jgs-fluentd ~]# cat /etc/yum.repos.d/td.repo
[treasuredata]
name=TreasureData
baseurl=http://packages.treasuredata.com/3/redhat/$releasever/$basearch
gpgcheck=1
gpgkey=https://packages.treasuredata.com/GPG-KEY-td-agent

fluentd를 시작하고 살펴보자.:

[root@jgs-fluentd ~]# systemctl start td-agent

[root@jgs-fluentd ~]# ss -nltp |grep fluentd
LISTEN     0      128          *:8888                     *:*                   users:(("ruby",pid=31738,fd=15),("fluentd",pid=31733,fd=15))

[root@jgs-fluentd ~]# ls -l /opt/td-agent/
total 40
drwxrwxr-x. 2 root root 4096 May 18 21:33 bin
drwxrwxr-x. 7 root root 4096 May 21 11:13 embedded
drwxrwxr-x. 5 root root 4096 May 21 11:13 etc
-rw-rw-r--. 1 root root 3783 May 18 21:33 LICENSE
drwxrwxr-x. 2 root root 4096 May 21 11:12 LICENSES
drwxrwxr-x. 4 root root 4096 May 21 11:13 usr
-rw-rw-r--. 1 root root 8690 May 18 21:33 version-manifest.json
-rw-rw-r--. 1 root root 3761 May 18 21:33 version-manifest.txt

[root@jgs-fluentd ~]# ls -l /var/log/td-agent/
total 8
drwxr-xr-x. 3 td-agent td-agent 4096 May 21 11:21 buffer
-rw-r--r--. 1 td-agent td-agent 3111 May 21 11:21 td-agent.log

프로세스.:

[root@jgs-fluentd ~]# ps auxww |grep td-agent
td-agent 31733  0.0  0.4 241296 37716 ?        Sl   11:21   0:00 /opt/td-agent/embedded/bin/ruby /opt/td-agent/embedded/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid
td-agent 31738  0.0  0.6 257592 55040 ?        Sl   11:21   0:01 /opt/td-agent/embedded/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/embedded/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid --under-supervisor
  • td-agent가 시작되면 마스터와 슬레이브 두 프로세스가 시작된다.
  • 마스터 프로세스는 슬레이브 프로세스의 수명주기를 관리하고,
  • 슬레이브가 실제 로그를 수집한다.

input 설정에 따라 아래 포트가 열린다.

  • in_tail : notthing
  • in_forward : tcp/24224, udp/24224
  • in_unix : /var/run/td-agent/td-agent.sock

에이전트 설정파일은 아래 위치한다.:

/etc/td-agent/td-agent.conf
  • 기본 설정은 HTTP에서 로그를 가져와서 stdout(/var/log/td-agent.log) 으로 라우트 하도록 구성되어 있다.

curl 명령을 사용하여 샘플 로그 레코드를 게시해보자.:

[root@jgs-fluentd ~]# curl -X POST -d 'json={"json":"message"}' http://localhost:8888/debug.test

stdout으로 설정된 /var/log/td-agent.log를 확인해보자.:

[root@jgs-fluentd ~]# tail -n1 /var/log/td-agent/td-agent.log
2019-05-21 11:29:33.743030358 +0900 debug.test: {"json":"message"}

이제 Fluentd를 사용하여 실제 로그를 수집할 준비가 되었다.

플러그인

Fluentd는 아래 7가지 플러그인 유형이 있다.

  • Input
  • Parser
  • Filter
  • Output
  • Formatter
  • Storage
  • Buffer : 이것은 중요한 부분이라 아래 자세히 정리한다.

Buffer

Buffer 플러그인은 output 플러그인 안에서 사용된다.

예를들어, out_s3(출력 플러그인) 은 기본적으로 buf_file을 사용하여 실제 S3로 로그 데이터를 전송하기 전에 버퍼 파일에 임시로 저장한다.

  • 버퍼는 file 혹은 메모리를 사용할 수 있다.

buffer 작동원리

버퍼는 chunk의 집합이다. Chunk는 단일 blob으로 연결되는 이벤트의 모음이다.

chunk를 화물상자라고 생각하면 된다. buffer plugin은 chunk를 경량 컨테이너로 사용하고, input source에서 들어오는 이벤트로 채우기 시작한다. chunk가 가득 차면 도착지로 배송한다.

내부적으로는 buffer plugin은 chunk를 저장할 두개의 분리된 장소를 사용한다.

  • stage : chunk가 이벤트로 채워지는 장소
  • queue : chunk가 배송전에 대기하는 대기열

chunk flow:

input event -> buffer(chunk) -> Queue(chunk) -> Output

Config File Syntax

설정파일은 Fluentd가 가질 input 또는 listeners 를 정의할 수 있고, Fluentd는 이벤트 데이터를 특정 output으로 라우팅 하기 위해 규칙을 설정한다.

설정 파일은 아래 문법으로 구성된다.

  • source : 이것은 input source를 나타낸다. (로그를 어디서 수집할건지)
  • match : 이것은 output 의 대상을 나타낸다. (로그를 어디에 쓸건지)
  • filter : 이것은 이벤트 처리 파이프라인을 결정한다. (로그를 output에 보내기 전 사용자 정의 필터를 할 수 있음)
  • system : 이것은 시스템 전체 구성을 설정한다.
  • label : 이것은 output, filter를 그룹화한다.
  • @include : 이것은 다른 파일을 include한다.

input과 output

아래는 in_http 와 out_stdout 플러그인을 예제로 이벤트 사이클을 살펴본다.:

<source>
  @type http
  port 8888
  bind 0.0.0.0
</source>
  • <source> 섹션은 데이터를 수집할 input 플러그인을 선택하여 구성한다.
  • <source> 섹션에서 @type 에 플러그인을 지정하는데, http 플러그인은 Fluentd가 HTTP 엔드포인트로 전환하여 HTTP로 들어오는 메시지를 수집한다.
  • 이제 http 포트 8888에서 들어오는 메시지를 Fluentd가 수집할 것이다.

그럼 이제 수집한 데이터를 어디로 보낼지? output을 지정하자.:

<match test.cycle>
  @type stdout
</match>
  • <match>는 데이터를 매칭하여 어디로 데이터를 보낼건지를 정하는데, 이 매칭할 조건이 tag기준이다.
  • <match test.cycle>에서 test.cycle이 tag이다.
  • @type 으로 stdout을 정의했고, 이는 그냥 표준출력인 터미널로 데이터를 보낸다(output).

그럼 이제 http 포트 8888로 데이터를 보내고 Fluentd가 이 데이터를 수집해서 output인 터미널로 출력하는지 확인해보자.:

[root@jgs-fluentd td-agent]# curl -X POST -d 'json={"action":"login","user":2}' http://localhost:8888/test.cycle

[root@jgs-fluentd td-agent]# tail -f /var/log/td-agent/td-agent.log
...
2019-05-23 17:42:04.828064560 +0900 test.cycle: {"action":"login","user":2}
  • td-agent가 백그라운드 데몬으로 실행했기 때문에 stdout이 없고, stdout으로 출력되는 로그를 확인했다.
  • 매칭할 태그를 선정하는 기준이 http://localhost:8888/<Tag> 와 같은 형태이다.
  • http 포트 8888로 들어온 input 데이터를 output으로 잘 출력했다.

데이터는 크게 3가지 파트로 구성된다. * Time : 로그 데이터의 생성시간 * Record : 로그 데이터의 내용으로 JSON 형태로 정의된다. * Tag : 데이터의 분류이다. 각 로그 레코드는 tag를 통해서 로그의 종류가 정해진다. 이 tag에 따라서 로그에 대한 필터링, 라우팅과 같은 플러그인이 적용된다.

위 output으로 출력된 데이터를 기준으로 설명하자면 아래와 같다.

  • Time : 828064560 +0900
  • Tag : test.cycle:
  • Record : {“action”:”login”,”user”:2}

Filter

필터는 input에서 output으로 이동 하기 전에 input에서 받은 이벤트를 output으로 통과 시키거나 거부하는 규칙을 설정할 수 있다.

필터 규칙을 설정해보자.:

<source>
  @type http
  port 8888
  bind 0.0.0.0
</source>

<filter test.cycle>
  @type grep
  <exclude>
    key action
    pattern ^logout$
  </exclude>
</filter>

<match test.cycle>
  @type stdout
</match>
  • <fileter test.cycle> : 필터를 정의하고 test.cycle이라는 태그가 매칭되면 이 태그의 데이터를 검사한다.
  • @type grep : 특정 문자열을 grep하기 위해 grep 플러그인을 사용했다.
  • <exclude> 필터에 의해 exclude될 데이터에 대한 규칙을 정한다.
  • key action : 로그 데이터의 action 키에 ^logout$ value가 포함되어 있으면 이 로그 데이터는 output에 도달하지 못하고 버려진다.
  • patthern : regex로 필터할 데이터 규칙을 정한다.

아래 두 curl 명령으로 결과의 차이를 확인해보자.:

[root@jgs-fluentd td-agent]# curl -X POST -d 'json={"action":"login","user":2}' http://localhost:8888/test.cycle
[root@jgs-fluentd td-agent]# curl -X POST -d 'json={"action":"logout","user":2}' http://localhost:8888/test.cycle

[root@jgs-fluentd td-agent]# tail -f /var/log/td-agent/td-agent.log
...
2019-05-23 19:02:37.625941479 +0900 test.cycle: {"action":"login","user":2}
  • 두 http 요청에 의해 하나만 output으로 출력이 되었다.
  • action 키의 logout value는 필터에 의해 output으로 도달하지 못하고 필터가 된것이다.

필터의 설정은 위에서 아래 순서대로 처리되는 단계별 절차를 따른다. 그래서 많은 필터가 사용될 경우 설정파일이 복잡해진다.

그래서 이에 대한 대응으로 여러 필터를 통합할 수 있는데, 이 방법이 label이다.

labels

label 은 구성 파일을 복잡성을 해결하고 위쪽에서 아래쪽 순서를 따르지 않는다.

라벨에 키 값에 링크된 새 라우팅 섹션에서 이를 처리한다.

아래 예시를 보자.:

<source>
  @type http
  port 8888
  bind 0.0.0.0
  @label @STAGING              <----레이블 추가
</source>

<filter test.cycle>
  @type grep
  <exclude>
    key action
    pattern ^login$
  </exclude>
</filter>

<label @STAGING>               <----이 레이블로 라우팅
  <filter test.cycle>
    @type grep
    <exclude>
      key action
      pattern ^logout$
    </exclude>
  </filter>

  <match test.cycle>
    @type stdout
  </match>
</label>
  • input 소스에 STAGING 라벨을 부여했고,
  • <label @STAGING> 에서 직접 해당 input 데이터에 대한 필터 및 ountput 처리함.
  • <source> 섹션 바로 아래에 있는 필터는 무시되고, <label> 섹션 안에서 필터처리를 한다.

결과를 보자.:

[root@jgs-fluentd td-agent]# curl -X POST -d 'json={"action":"logout","user":2}' http://localhost:8888/test.cycle
[root@jgs-fluentd td-agent]# curl -X POST -d 'json={"action":"login","user":2}' http://localhost:8888/test.cycle

[root@jgs-fluentd td-agent]# tail -f /var/log/td-agent/td-agent.log
...
2019-05-23 22:50:23.228286212 +0900 test.cycle: {"action":"login","user":2}
  • action : logout 과 login에 대한 HTTP 요청을 했다.
  • 실제로 수집하여 output까지 전달된 데이터는 login이다
  • <source> 섹션 바로 아래에 있는 필터인 login이 필터되지 않았고, <label> 섹션안에 있는 필터로 logout만 필터되었다.

이제 이 로그를 Elastic Search와 연결하여 로그를 Elastic Search 로 저장하자.

이렇게 하기 위해서는 Elasticsearch 플러그인이 필요하다.:

[root@jgs-fluentd ~]# td-agent-gem install fluent-plugin-elasticsearch

먼저 elasticsearch 서버를 구성하자.

Fluentd 에서 ES로 로그 전송

Fluentd에서 /var/log/messages 로그를 수집하여 ES에 저장하는 설정을 하자.

Flentd 설정.:

[root@jgs-fluentd td-agent]# cat td-agent.conf
<source>
  @type tail
  path /var/log/messages
  pos_file /var/log/td-agent/messages.log.pos
  tag messages.log
  format json
</source>

<match messages.log>
  @type elasticsearch
  host 172.20.1.11
  port 9200
  logstash_format true
</match>
  • in_tail 플러그인으로 /var/log/messages 로그를 수집한다.
  • 수집한 데이터는 in_elasticsearch 플러그인으로 172.20.1.11(ES server)로 보낸다.

Kibana

Kibana는 강력하고 화려한 그래픽을 통해 데이터를 작업할 수 있도록 해주는 오픈소스 데이터 시각화 플랫폼이다.

여기선 ES에 저장된 로그 데이터를 시각화하기 위해 Kibana를 사용한다.

Kibana를 설치한다.:

[root@jgs-es ~]# wget https://artifacts.elastic.co/downloads/kibana/kibana-5.4.0-x86_64.rpm
[root@jgs-es ~]# rpm -ivh kibana-5.4.0-x86_64.rpm
  • jgs-es 서버에 Kibana를 설치하였다.

프로세스 및 포트.:

[root@jgs-es ~]# ps -ef |grep kibana
kibana    4385     1  9 12:13 ?        00:00:03 /usr/share/kibana/bin/../node/bin/node --no-warnings /usr/share/kibana/bin/../src/cli -c /etc/kibana/kibana.yml

[root@jgs-es ~]#  ss -nltp
LISTEN     0      128                    127.0.0.1:5601                                       *:*                   users:(("node",pid=4385,fd=11))

kibana 설정.:

[root@jgs-es ~]# vi /etc/kibana/kibana.yml
...
server.host: "0.0.0.0"
]]>
Mon, 10 Jun 2019 00:00:00 +0900