카테고리 보관물: config

CIDR(Classless Inter-Domain Routing) 표기법

인터넷 주소 체계인 IP는 간혹 ‘1.1.1.1/32’와 같은 형태로 표기됩니다. 앞부분인 1.1.1.1이 IP인것은 알겠는데 /32이 무엇을 의미 하는지 모르는 분들을 위해 오늘은 /32이 무엇을 의미하는지 알려 드리겠습니다.

IP는 마침표로 구분되는 4개의 영역을 가지고 있습니다. 각각의 영역을 옥텟이라고 부르며 1개의 옥텟에 1byte의 크기를 가집니다. 0~255까지 표현이 가능하며 총 4byte(32bit)의 크기를 가집니다.

이러한 구성의 가진 IP는 효율적으로 사용하기 위해 Net ID와 Host ID로 나누어 사용합니다.

Net ID는 네트워크 영역을 식별하기 위한 값이며 Host ID는 하나의 네트워크 영역에서 호스트를 식별하기 위한 값입니다.

위에 그림처럼 Net ID는 좌측 비트부터 사용하게 되는데 옥텟과 마침표만 을 사용하면 어디까지가 Net ID이고 Host ID인지 알수 있는 방법이 없습니다.
때문에 보편적으로 CIDR(Classless Inter-Domain Routing)의 유연성있는 서브넷 마스크 표기법을 이용하여 표현합니다.

Subnet mask 표기법 -> 1.1.1.1 (255.255.255.255)
CIDR(prefix) 표기법 -> 1.1.1.1/32

위에서 표현한 1.1.1.1/32는 좌측부터 32비트가 전부 Net ID라는 뜻이며 1.1.1.1은 하나의 호스트 IP를 나타냅니다.
만약 1.1.1.0/24와 같이 표현된다면 좌측에서 부터 24비트, 즉 1.1.1까지는 Net ID라는 뜻이며 1.1.1.0 ~ 1.1.1.255가 1.1.1.0대역 네트워크에서 보유한 호스트 들이 됩니다.

해당 내용을 이용하여 방화벽을 설정할 경우 1.1.1.0/24로 설정하여 1.1.1.0~1.1.1.255에 해당 하는 256개의 ip를 CIDR표현식 한 줄로 설정할 수 있게 됩니다.

시놀로지 NAS의 OpenVPN 서버 설정하기

Synology NAS의 PPTP VPN 서버 설정 방법을 이전 포스트에서 설명했는데 한가지 설명을 빠트렸었다. 무엇인고 하니 설명한 환경에서 NAS를 SuperDMZ 또는 DMZ(NAT) 기능을 이용해 집의 인터넷 공유기에 할당되는 공인IP를 통채로 NAS에 할당한 경우에만 가능한 방법이다.

그렇지 않고 통신사에 연결되는 인터넷 공유기에는 공인IP가 할당되고 NAS에는 192.X.X.X로 표시되는 사설IP가 할당될 경우에는 PPTP, IPSEC 등의 VPN은 정상동작시키기 쉽지 않다. 인터넷 공유기에서 포트포워딩을 해줘야할 포트도 여러개인데다 설정을 하더라도 제대로 동작하지 않는 경우가 많기 때문이다.

그래서 오늘은 하나의 포트만 포트포워딩 하면 사용할 수 있는 OpenVPN 서버의 설정방법을 포스팅한다.

1. 인터넷 공유기에서 OpenVPN에서 사용할 통신포트를 포트포워딩 하기

통신사에서 제공하는 인터넷 공유기의 경우 다음과 같이 “포트포워딩(Port Forwarding)” 기능을 제공하는 경우가 대부분이다.

2. 시놀로지 NAS에서 새 인증서 만들기

많은 시놀로지 사용자들이 OpenVPN 서버를 설정하면서 부닥치는 가장 큰 난관은 바로 인증서 설정과 관련된 부분이다. 일단 “인증서”가 뭔지 제대로 이해를 하지 못하고 있기 때문이다.

(기존의 기본 인증서로 설정해도 관계 없다. 생성하는 과정만 건너 뛰면 모든 작업은 동일하다.)

먼저 “제어판”에서 “보안” 메뉴를 선택하면 표시되는 “인증서” 탭을 선택한다.

 

synology nas의 Certificate tab
Synology NAS의 제어판-보안 메뉴의 인증서 탭

 

“추가” 버튼을 누르고 “인증서 생성” 창이 실행되면 “새 인증서 추가” 를 선택한 다음 “다음” 버튼을 누른다.

“설명” 에는 적당한 설명을 넣는다. 그리고 “자체 서명 인증서 생성”을 선택한다.

 

synology nas에서 self-sign certificate 만들기
자체 서명 인증서 생성

 

다음과 같이 루트(CA) 인증서 생성에 필요한 기본값을 입력한다. 대충 입력해도 된다.

 

시놀로지 NAS의 셀프사인 인증서 생성
루트 인증서(CA) 생성

 

루트(CA) 인증서를 만들 정보를 입력하고 나면 실제 통신 시 사용할 인증서를 만들게 된다. 입력하는 정보가 아주 조금 다른데… 대충~ 에러가 나지 않도록만 입력하면 된다.

 

시놀로지 NAS에 인증서 만들기

 

“적용” 버튼을 누르면 다음과 같이 인증서가 반들어진다. 그리고 인증서의 유효기간은 생성한 날로부터 1년이다.

 

Synology NAS에 만들어진 Self-sign Certificate
Synology NAS에 만들어진 자체 서명 인증서

 

3. VPN 서버가 새로 만든 인증서를 사용하도록 설정하기

“제어판” – “보안” – “인증서” 탭에서 “구성” 버튼을 누르면 인증서를 사용하는 서비스가 사용할 인증서를 선택할 수 있는 화면이 표시된다.

아래 화면처럼 “VPN Server”가 앞에서 새로 생성한 인증서를 사용하도록 선택해준다.

 

VPN Server가 사용할 인증서 선택하기

 

4. OpenVPN 서버 설정하기

이제 OpenVPN 서버를 설정해줘야 한다.  VPN Server를 설정하기 위해서 VPN Server를 실행하고 “OpenVPN” 메뉴를 선택한다.

그리고 “OpenVPN 서버 활성화”를 체크해준 뒤 다음과 같이 설정한다.

 

 Synology NAS의 OpenVPN Server
Synology NAS의 OpenVPN 서버

 

여기서 중요한 것은 “포트” 항목에 앞의 인터넷 공유기에서 NAS의 IP인 192.168.219.102의 포트포워딩 포트인 10472를 “포트” 항목에 입력하는 것이다.

그리고 나서 “적용” 버튼을 눌러 OpenVPN 서버를 실행한다.

 

OpenVPN 서버 실행

 

OpenVPN 서버를 실행하면 화면 아래에 보이는 “내보내기 구성” 버튼이 활성화된다.

이 버튼을 눌러 OpenVPN 클라이언트에서 OpenVPN 서버에 접속할 때 사용할 “설정 파일”을 저장한다.

 

OpenVPN 설정 내보내기

 

이 OpenVPN 접속 설정 파일을 적당한 이름으로 저장한다. 위에서는 synology-openvpn(10472).zip 파일로 저장했다. 그리고 하나의 파일을 더 저장해야 한다. 바로 인증서 파일이다.

5. 인증서를 파일로 저장하기

다시 인증서 화면으로 간 뒤 아래 화면처럼 새로 생성한 인증서 파일을 “인증서 내보내기” 버튼을 눌러 PC에 저장한다.

 

Synology NAS의 인증서 내보내기

 

인증서 파일은 기본적으로 archive.zip 파일로 저장된다.

지금가지 두개의 파일을 PC에 저장했다. OpenVPN 클라이언트에서 사용할 접속 설정 파일과 인증서 파일 두 개다. 이제 이 두개 파일의 압축을 해제한 뒤 편집해야 한다.

6. OpenVPN 클라이언트 구성 파일 편집

Synology에서 제공하는 VPN 서버의 버그인지… 아니면 원래 그런 것인지 모르겠지만 앞에서 다운로드 받은 OpenVPN 클라이언트 접속 용 구성 파일은 인증서 정보가 제대로 설정되어 다운로드 되지 않는다. 그래서 수동으로 인증서 내용을 편집해 넣어줘야 한다.

먼저 다음과 같이 인증서가 저장된 archive.zip과 OpenVPN 접속 설정파일인 synology-open….zip 파일의 압축을 해제한다.

 

인증서 파일과 OpenVPN 접속 구성파일 압축해제

 

인증서 압축파일을 해제하면 4개의 파일이 표시되는데 cert.pem 파일과 prikey.pem 파일의 내용을 OpenVPN 접속 구성 파일에 추가해줘야 한다.

 

인증서 압축파일 해제하면 표시되는 4개의 파일

 

OpenVPN 접속 구성 파일이 포함된 zip 파일을 압축해제하면 VPNConfig.ovpn 이라는 OpenVPN 접속 용 구성파일이 보인다. 이 파일을 Notepad 등으로 열어준다.

 

OpenVPN 접속 용 구성파일 열기

 

먼저 상단에 위치한 YOUR_SERVER_IP를 인터넷 공유기에 할당된 외부 공인IP로 수정한다. 만약 시놀로지의 DDNS를 이용해 xxx.synology.me 와 같은 도메인주소를 사용한다면 그 도메인주소를 입력해주면 된다.

 

ovpn파일 편집하기

 

다음은 새로운 Notepad을 열어 인증서 파일들 중 cert.pem 파일을 다음과 같이 연다.

 

cert.pem
cert.pem 파일

 

위의 cert.pem 파일의 내용 전체를 다음과 같이 VPNConfig.ovpn 파일을 열고 가장 아래부분의 </ca> 뒷 부분에 <cert> 태그를 추가하고 그 뒤에 붙여넣는다.

 

.ovpn 파일의 가장 뒤에 cert.pem 파일의 내용을 붙여 넣는다.

 

그리고 가장 뒷 부분에 </cert>을 추가한다.

마찬가지로 인증서 파일들 중 prikey.pem 파일의 내용을 모두 복사해 VPNConfig.ovpn 파일의 맨 뒷 부분에 <key> 태그를 추가한 뒤 붙여넣는다.

 

.ovpn 파일의 끝에 prikey.pem 파일의 내용을 추가한다.

 

그리고 맨 끝에 </key>를 추가해준 뒤 저장한다.

여기까지 진행하면 OpenVPN 클라이언트 프로그램이 OpenVPN 서버에 접속할 때 사용할 구성파일이 완성된다.

7. OpenVPN Client 설치하고 접속 구성 파일 복사하기

OpenVPN 서버에 접속하여 암호화 된 안전한 Private(사설) 네트워크를 만들기 위해서는 OpenVPN GUI라는 클라이언트 프로그램을 설치하여야 한다. 다운로드는 여기에서 받으면 된다.

기본 옵션으로 설치한 뒤 앞에서 편집한 VPNConfig.ovpn 파일을 아래와 같이 기본 config 경로에 복사한다.

 

.ovpn 파일 복사하기

 

이 때 관리자권한이 필요한데 관리자 권한을 부여하여 복사해 넣으면 된다.

8. OpenVPN 서버에 OpenVPN GUI로 접속하기

설치하고 나면 VPNConfig 라는 접속 구성이 보인다. 아래와 같이 “연결”을 눌러 OpenVPN 서버에 접속하면 된다.

 

OpenVPN GUI를 통해 접속하기

 

ID와 비밀번호를 묻는 창이 실행되면 시놀로지의 접소계정을 입력하면 된다. 다만 해당 계정은 시놀로지 DSM에서 OpenVPN 접속이 허용된 계정이어야 한다.

 

OpenVPN 서버에 접속하기
시롤로지 OpenVPN 서버에 접속하기

 

접속이 되면 다음과 같이 접속상태를 확인할 수 있고 “연결해제” 버튼을 눌러 VPN 네트워크를 파괴하여 접속을 끊을 수도 있다.

 

Synology NAS 오픈VPN 접속 상태

Boot2Docker Volume Disk Resize

Boot2Docker에서 “장치에 남은 공간 없음” 오류가 발생합니까?

많은 수의 이미지와 함께 Boot2Docker를 사용하거나 작업 중인 이미지가 매우 큰 경우 Boot2Docker VM의 볼륨 공간이 부족하면 문제가 발생할 수 있습니다. 솔루션은 먼저 볼륨을 복제한 다음 디스크 파티셔닝 도구를 사용하여 크기를 조정하여 볼륨 크기를 늘리는 것입니다. (GParted)[ http://gparted.sourceforge.net/download.php/index.php ]는 무료 ISO이고 VirtualBox와 잘 작동하기 때문에 사용하겠습니다.

1. Boot2Docker의 VM을 중지합니다.

$ boot2docker stop 

Boot2Docker는 VirtualBox의 기본 도구로 크기를 조정할 수 없는 VMDK 이미지와 함께 제공됩니다. 대신 VDI 볼륨을 만들고 VMDK 볼륨을 여기에 복제합니다.

2. VirtualBox 명령줄 도구를 사용하여 VMDK 이미지를 VDI 이미지로 복제합니다.

$ vboxmanage clonehd /full/path/to/boot2docker-hd.vmdk /full/path/to/<newVDIimage>.vdi —format VDI —variant Standard

3. 필요에 적합한 크기를 선택하여 새 복제 볼륨의 크기를 조정합니다. 많은 컨테이너를 회전하거나 컨테이너가 특히 큰 경우 더 큰 것이 좋습니다.

$ vboxmanage modifyhd /full/path/to/<newVDIimage>.vdi —resize <size in MB>

4. (GParted)[ http://gparted.sourceforge.net/download.php/ ] 와 같은 디스크 파티션 도구 ISO를 다운로드합니다 . Boot2Docker VM의 IDE 버스에 ISO를 추가합니다. ISO를 추가하기 전에 버스를 생성해야 할 수도 있습니다.

5. VirtualBox의 Boot2Docker 이미지에 새 VDI 이미지를 추가합니다.

6. Boot2Docker VM에 대한 설정에서 CD/DVD가 부팅 순서 목록 의 맨 위에 있는지 확인 합니다.

7. VirtualBox에서 Boot2Docker VM을 시작하면 디스크 파티션 ISO가 시작됩니다. 

GParted를 사용하여 GParted Live(기본 설정) 옵션을 선택합니다. 기본 키보드, 언어 및 XWindows 설정을 선택하면 GParted 도구가 시작되고 생성한 새 VDI 볼륨이 표시됩니다. VDI를 마우스 오른쪽 버튼으로 클릭하고 크기 조정/이동 을 선택합니다 . 볼륨을 나타내는 슬라이더를 최대 크기로 끌어 크기 조정/이동 을 클릭 한 다음 적용 을 클릭 합니다. GParted를 종료하고 VM을 종료합니다. VirtualBox의 Boot2Docker VM용 IDE 컨트롤러에서 GParted ISO를 제거합니다.

8. VirtualBox에서 또는 명령줄( boot2docker start)을 사용하여 Boot2Docker VM을 시작하여 볼륨 변경 사항이 적용되었는지 확인합니다.

Apache에서 gzip을 이용한 압축전송하기

웹서비스 최적화 방법중에 하나로 gzip 압축전송이 있습니다.
gzip은 파일 압축에 쓰이는 응용 소프트웨어로 GNU zip의 준말이며 무료 소프트웨어이다(출처: 위키백과)
이를 사용하기 위해서는 사용하는 브라우저가 지원을 해야합니다.
(브라우저에서 request headers > “Accept-Encoding”에 gzip이 포함되어 있어야 합니다.)

마찬가지로 서버에서도 gzip으로 전송해야 합니다.
(response headers > “Content-Encodding:gzip”)

배경

일반적인 Http Request & Response와 gzip사용시 차이점을 간단히 설명하면 다음과 같습니다.

1.브라우저에서 index.html을 서버에 요청합니다.

2.서버는 해당 파일을 찾습니다.

3.파일을 요청한 브라우저로 전송합니다(100KB).

4.브라우저는 해당 파일을 표시합니다.

 

 

1.브라우저에서 index.html을 서버로 요청시 gzip을 지원한다는 내용을 서버로 전달합니다.

2.서버는 해당 파일을 찾습니다.

3.gzip으로 파일을 압축해서 보냅니다(30KB).

4.브라우저에서 압축된 파일을 풀고 표시합니다.

테스트 환경

  • 서버 OS: Windows7
  • 웹서버: Apache 2.4
  • 브라우저: IE9, 크롬, Firefox, Safari
환경설정

1.Apache httpd.conf 파일 열기
2.LoadModule 영역에서 아래내용에 주석처리 되었으면 해제합니다.

LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule filter_module modules/mod_filter.so
3.적당한 위치에 아래 내용을 추가합니다.
<IfModule mod_deflate.c>

        AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/x-javascript

        DeflateCompressionLevel 9

        BrowserMatch ^Mozilla/4 gzip-only-text/html  # Netscape 4.xx에는 HTML만 압축해서 보냄
        BrowserMatch ^Mozilla/4\.0[678] no-gzip  # Netscape 4.06~4.08에는 압축해서 보내지 않음
        BrowserMatch \bMSIE !no-gzip !gzip-only-text/html  # 자신을 Mozilla로 알리는 MSIE에는 그대로 압축해서 보냄
        
        ##예외 설정
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|bmp|zip|gz|rar|7z)$ no-gzip dont-vary
        
        ####로그설정.
        ##DeflateFilterNote Input instream
        ##DeflateFilterNote Output outstream
        ##DeflateFilterNote Ratio ratio
        ##
        ##LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
        ##CustomLog logs/deflate_log deflate

4.아파치를 restart 시킨 후 아래 사이트에서 gzip전송이 정상동작하는지 테스트 합니다.

http://www.whatsmyip.org/http-compression-test/

 

위 결과 페이지에서는 특정페이지가 84.5% 절감되고 있습니다.

Response Headers 내용은 아래와 같습니다.

 

 

 

 

 

※ 3번 “로그설정” 주석해제 후 apache logs폴더에 생성된 deflate_log파일을 보면 압축률을 확인할 수 있습니다.

.

"GET /nexacro14lib/framework/SystemBase.js HTTP/1.1" 23987/176486 (13%)
"GET /nexacro14lib/framework/Platform_HTML5.js HTTP/1.1" 18786/138984 (13%)
"GET /nexacro14lib/framework/ErrorDefine.js HTTP/1.1" 4886/18684 (26%)
"GET /nexacro14lib/framework/CssObjs.js HTTP/1.1" 25266/271916 (9%)
"GET /nexacro14lib/framework/BasicObjs.js HTTP/1.1" 9152/50003 (18%)
"GET /nexacro14lib/framework/Platform.js HTTP/1.1" 58726/370077 (15%)
"GET /nexacro14lib/framework/SystemBase_HTML5.js HTTP/1.1" 50261/334443 (15%)
"GET /nexacro14lib/component/CompBase/CompBase.js HTTP/1.1" 28574/167299 (17%)
"GET /nexacro14lib/component/CompBase/CompEventBase.js HTTP/1.1" 17397/255753 (6%)

미리 gzip으로 압축후 사용할 순 없을까?
gzip 사용시 단점은 요청시 gzip으로 압축하는 과정으로 인해
서버의 CPU사용량이 gzip을 사용하지 않을 때 보다 증가한다는 것이다.
그렇다면 거의 변할 일이 없는 file은 미리 압축해서 사용하는것도 괜찮지 않을까?
1.gzip으로 압축하기
Online YUI Compressor에 접속 후 아래그림 처럼 소스를 gz파일로 변환한다.
① 원하는 소스를 붙여넣기 한다.
② 결과는 “Redirect to gzipped output”을 선택한다.
③ “Compress”버튼을 누르면 잠시 후 파일을 저장할 수 있는 팝업창이 표시된다.
④ “gz”확장자로 원하는 위치와 파일명으로 저장합니다.

 

 

2.해당 파일을 영역안에 포함시킵니다.
<script type="text/javascript" src="./pkg/EcoBasic.js.gz"></script>
3.위와 같이 하고 해당페이지에 접속하면 아래처럼 log가 발생하고 정상적으로 load되지 않습니다(크롬).
Content-Encoding:gzip
Content-Type:application/x-gzip

Resource interpreted as Script but transferred with MIME type application/x-gzip: "http:// ~ /pkg/EcoBasic.js.gz". 
4.Apache httpd.conf 파일의 LoadModule 영역에서 아래내용에 주석처리 되었으면 해제합니다.
​LoadModule dir_module modules/mod_dir.so
  아래 2줄을 주석처리 되어있으면 해제합니다.
AddEncoding x-compress .Z
AddEncoding x-gzip .gz .tgz
  아래 2줄을 주석처리 합니다.
#AddType application/x-compress .Z
#AddType application/x-gzip .gz .tgz
  아래 내용도 추가해야 한다고 나와있었는데 실제로 해보니 적용하지 않아도 처리되었습니다(참고하세요).
  :gz 확장자에 대해서 강제로 content-encoding을 설정하는 내용입니다.
# root .
<Directory /~/EcoPkg>
    Options Indexes MultiViews FollowSymLinks
    #AllowOverride None
    #Order deny,allow
    #Deny from all
    #Allow from 127.0.0.0/255.0.0.0::1/128 

    AddEncoding gzip gz
    <FilesMatch "\.gz$">
      ForceType text/plain
      Header set Content-Encoding: gzip
    FilesMatch>
    
##   <FilesMatch "\.css\.gz$">
##        ForceType text/css
##        Header set Content-Encoding: gzip
##    FilesMatch>
Directory>
5.설정 후 아파치 restart후에 Response Headers를 확인하면 다음과 같습니다.

 

 

 

 

 

마치며…

※ RUNTIME(2014,9,3,1 버전 기준)에서는 지원하지 않습니다.
이미지와 PDF파일은 gzip으로 압축하지 않는다(이미 압축되어 있음).
gzip을 지원하는 브라우저 목록(출처: webmasters.stackexchange.com, 참고: schroepl.net)
  • Netscape 6+ (Netscape 4-5 does, but with some bugs).
  • Internet Explorer 5.5+ (July 2000) and IE 4 if set to HTTP/1.1.
  • Opera 5+ (June 2000)
  • Firefox 0.9.5+ (October 2001)
  • Chrome since forever
  • Safari since forever (as far as I can tell)
이 글에서는 Apache httpd.conf 파일을 이용한 예제가 작성되었지만 .htaccess 파일을 이용할 수 도 있다.

시놀로지 4TB디스크를 8TB디스크로 교체하기

DS918+와 4TB 하드디스크 한 개를 사용하고 있는데요. 8TB 하드디스크 네 개로 교체하고 싶어요.

  • 4TB 하드디스크의 공간이 가득 찼습니다. 8TB 하드디스크 4개 장착 후 raid5를 만들어서 24TB의 공간을 사용하고 싶습니다.
  • 나스는 24시간 계속 사용합니다. 8TB 하드디스크로 교체하는 동안에도 나스 접속이 끊기지 않아야 합니다.

8TB 하드디스크 4개를 raid5로 만듭니다.

DS920+는 핫스왑 기능을 제공하므로 나스를 계속 사용하면서 하드디스크를 교체할 수 있습니다. 8TB 하드디스크 4개를 사용하여 raid5가 완성되는 데는 5일 정도 소요 되었지만 실제로 작업한 시간(하드디스크 교체하기, 마우스 클릭하기 등)은 10분 정도밖에 되지 않습니다.

  • 현재는 1번 베이에 4TB 하드디스크가 장착되어 있고 나머지 베이는 비어 있습니다. 스토리지 풀은 shr방식입니다. 다음 과정을 거쳐서 8TB 하드디스크 4개로 raid5를 만듭니다.
  • 과정 1
    4TB 디스크 1개와 8TB 디스크 1개를 레이드1으로 만듭니다. 레이드1이 된 이후에는 볼륨의 크기가 4TB가 됩니다.
  • 과정 2
    4TB 디스크를 8TB 디스크로 교체 후 수리를 진행합니다. 수리가 끝나면 8TB 디스크 2개로 raid1이 되고 볼륨의 크기가 8TB가 됩니다.
  • 과정 3
    8TB 디스크 2개로 raid1 상태에서 8TB 디스크 2개를 추가하여 raid5로 변경합니다. raid5가 된 이후에는 볼륨의 크기가 24TB가 됩니다.

과정 1. 4TB와 8TB로 raid1 만들기.

  • 2번 베이에 8TB 디스크를 장착 후 “스토리지 풀 > 작업 > 드라이브 추가”를 클릭합니다. 드라이브 2를 선택합니다.
  • 스토리지 풀 화면에서 1번 베이의 4TB 디스크와 2번 베이의 8TB 디스크가 사용된 것을 볼 수 있습니다.
  • 스토리지 풀 확장하는 작업이 완료되면 스토리지 풀의 총 용량은 4TB, 볼륨의 총 용량도 4TB가 됩니다.
  • 스토리지 풀 확장이 완료되는데 13시간 정도 소요되었습니다.

과정 2. 4TB 교체 후, 8TB와 8TB로 raid1 만들기.

  • HDD/SSD 화면에서 4TB 하드디스크에 해당하는 드라이브(이번 사례에서는 드라이브 1)를 선택 후 “작업 > 비활성화”를 클릭합니다.
  • 드라이브 1 옆에 “비활성화됨”이 표시되면 4TB 하드디스크를 제거하고 새로운 8TB 디스크를 장착합니다. (기존 4TB 드라이브와 미러링 된 드라이브 외 새로운 드라이브 추가)
  • “스토리지 풀 > 작업 > 수리”를 클릭합니다. 드라이브 1을 선택합니다.
  • 2번 베이 하드디스크(Drive 2)의 내용을 1번 베이 하드디스크(Drive 1)로 복제하므로 Drive 2는 읽기작업이 발생하고 Drive 1은 쓰기작업이 발생하는 것을 리소스 모니터에서 확인할 수 있습니다.
  • 수리가 완료되는데 15시간 정도 소요되었습니다
  • 수리가 완료되면 스토리지 풀의 총 용량은 8TB로 늘어나지만, 사용한 용량은 여전히 4TB 그대로입니다. shr방식을 사용하는 경우에는 볼륨의 크기가 저절로 늘어나지 않기 때문입니다.        (DSM 6.2.3 부터는 자동으로 최대 크기로 늘어남)
  • 볼륨의 크기를 8TB로 늘립니다. “볼륨 > 작업 > 구성”을 클릭하고 “최대” 버튼을 클릭합니다. 그러면 “할당된 크기 수정(GB)” 칸의 숫자가 스토리지 풀이 사용할 수 있는 최대 용량으로 입력됩니다. “확인” 버튼을 클릭하면 10초 정도 후에 볼륨의 총 용량이 8TB로 변경됩니다.

과정 3. 8TB 디스크 2개 추가하기.

  • 3번 베이, 4번 베이에 8TB 디스크를 각각 장착한 다음 “스토리지 풀 > 작업 > 드라이브 추가”를 클릭합니다. 드라이브 3, 드라이브 4를 선택하고 다음을 클릭합니다. “설정 확인” 화면에서 총 용량이 21.82TB로 나오는지 확인합니다.
  • 스토리지 풀 확장이 완료되는데 90시간 정도 소요되었습니다.
  • 스토리지 풀 확장하는 작업이 완료되면 스토리지 풀의 총 용량은 24TB로 늘어나지만, 사용한 용량은 여전히 8TB 그대로입니다.  사용하지 않은 용량 16TB를 볼륨에 추가해야 합니다.
  • “볼륨 > 작업 > 구성”을 클릭하고 “최대” 버튼을 클릭합니다.
  • 최종적으로 볼륨의 크기가 24TB가 되었습니다.

8TB 디스크의 파티션 모습.

지금까지의 과정은 이벤트 로그와 알림에 기록되어 있습니다. 기록을 보면 “과정 3. 8TB 디스크 2개 추가하기”에서 동기화 작업이 네 번 나오는데요. 4TB 하드디스크로 스토리지 풀을 최초로 만들때 shr방식으로 설정했기 때문입니다. shr방식에서 더 큰 용량의 하드디스크로 교체하면 하드디스크의 파티션이 최초의 스토리지 풀 크기(4TB)와 나머지 크기(8TB에서 최초의 스토리지 풀 크기를 제외한 나머지)로  나누어집니다.  그래서 8TB디스크 4개 모두 두 개의 파티션으로 나누어져 있습니다. 또한 raid1에서 raid5로 변경하는 경우에 디스크 두 개를 한 번에 추가해도 변경작업(동기화 작업)은 한 개씩 이루어집니다. 그래서 다음과 같이 총 네 번의 동기화 작업이 진행됩니다.

  • 첫 번째 : 디스크 3개의 4TB  파티션을 동기화.
  • 두 번째 : 디스크 3개의 4TB  파티션을 제외한 부분 동기화.
  • 세 번째 : 디스크 4개의 4TB  파티션을 동기화.
  • 네 번째 : 디스크 4개의 4TB  파티션을 제외한 부분 동기화.

네 번의 동기화가 모두 끝나면 두 개의 raid5 장치가 생성됩니다. 하나는 4TB 크기 네 개로 raid5이므로 사용가능한 용량은 12TB가 되고, 다른 하나는 8TB에서 4TB를 제외한 크기(결국 4TB 크기) 네 개로 raid5이므로 마찬가지로 12TB가 됩니다. 그리고 두 개의 12TB 공간을 LVM을 사용하여 묶어서 총 24TB 크기의 스토리지 풀이 됩니다.

  • 지금까지의 과정을 “모든 알림”에서 볼 수 있습니다.
  • fdisk 명령어를 사용해서 파티션이 어떻게 나눠져 있는지 확인할 수 있습니다.
  • sda5, sdb5, sdc5, sdd5가 md2에 사용되고 sda6, sdb6, sdc6, sdd6이 md3에 사용되었습니다.

Docker로 Hadoop 테스트 환경 구축하기 – HDFS

Docker와 테스트 환경

Docker는 애플리케이션을 컨테이너화해서 이미지로 만들어 배치하고 실행할 수 있는 환경을 제공하는 컨테이너 도구1이다.
격리된 파일 시스템을 갖는 컨테이너 특성 덕분에, 운영 환경에 대한 프로비져닝 뿐만 아니라 Docker가 설치된 환경에서 컨테이너화된 애플리케이션을 즉시 구동시켜서 테스트할 수 있는 환경을 구성하는데에도 유용하게 쓰인다.

오픈소스를 포함한 다양한 애플리케이션을 로컬 환경에 설치하고 구성하면서 테스트하다보면(주로 개발자의 노트북), 어느새 로컬 환경은 지저분해지고 몇 해 전에 설치한 애플리케이션이 자동 재시작되어 리소스를 점유하게 된다. 환경 설정 파일은 언제 어떻게 바꿨는지도 모른다. VM 환경으로 OS를 완전히 격리시켜 구성하자니 구동하는데 시간이 오래 걸리고 구동한 이후 점유하는 리소스가 노트북이 감당하기에는 참 크다.

Docker는 이런 환경에서 최적의 도구이다. 컨테이너를 어떻게 구성할지 애플리케이션마다 설정 파일을 생성하고, 서로 상호작용하는 애플리케이션인 경우 다시 실행과 관련된 설정 파일을 생성해서 여러 개의 애플리케이션을 순식간에 실행하고 다시 종료시킬 수 있다.

이 포스트에서는 Hadoop HDFS를 Docker로 컨테이너화 헤서 로컬에 테스트 환경으로 구성하는 방법을 설명한다.

HDFS

하둡 분산 파일 시스템(HDFS)은 마스터 노드인 NameNode와 워커 노드인 DataNode로 이루어져있다. 각각 JVM 위에서 동작하는 자바 애플리케이션으로, 두 애플리케이션만 동작을 하면 HDFS를 구성해서 읽고 쓸 수 있다.
실행 환경은 일반적은 GNU/Linux 그리고 Windows 환경을 지원하며, Hadoop 2.7~2.x2 버전은 Java 7, 8을 지원한다.3

클라이언트에서 각 애플리케이션과 직접 통신하는 포트 정보는 다음 표와 같다.

애플리케이션 기본포트 프로토콜 상세설명 관련 설정 항목
NameNode 50070 HTTP HDFS 상태 및 파일 시스템 조회용 Web UI dfs.http.address
9000 IPC 파일 시스템 메타데이터 관련 작업용 fs.defaultFS
DataNode 50075 HTTP 상태 및 로그 조회용 Web UI dfs.datanode.http.address
50010 TCP 데이터 전송 dfs.datanode.address
표 1. 클라이언트에서 HDFS와 직접 통신할 때 사용하는 포트 정보

이 자료들을 가지고 이제 본격적으로 Docker 컨테이너화를 진행해보자.

Dockerize

애플리케이션을 Docker에서 사용하는 설정 파일인 Dockerfile 양식에 맞게 구성한다. 이 설정 파일이 있으면 Docker 이미지 빌드가 가능하고, 생성한 이미지를 어디에서든 당겨와서(pull) 실행할 수 있다.

사실 이미지를 생성하는 것은 이 설정 파일 없이 직접 기반이 되는 OS 이미지로부터 컨테이너를 실행해서 쉘로 접속, 필요한 작업을 하고 이미지를 커밋해도 된다.
하지만 이 방식은 다음과 같은 문제점이 있다:

  • 이미지가 어떻게 생성되었는지 기록이 남지 않음
  • 따라서 작업한 내용을 다시 되돌리거나, 몇 가지 설정을 변경해서 새로운 이미지를 생성하기 어려움
  • 그리고 생성된 이미지를 신뢰하기 어려움. 따라서 다른 사람과 공유하는데에도 적합하지 않음

블록을 쌓아 올리듯 이미지를 만드는 Docker 세계에서는, 처음에는 조금 번거로워 보이더라도 Dockerfile로 이미지를 만드는 것에 익숙해지는 것이 좋다.

Base

NameNode 이미지를 만들기 전에, 먼저 각 컴포넌트의 밑바탕이 되는 이미지를 구성한다. 밑바탕 이미지는 다음과 같은 내용을 포함헤야 할 것이다.

  • Hadoop binary
  • Java
  • Common configurations

여기에서는 현재 2019년 8월 기준 Hadoop 2버전의 최신 버전인 2.9.2 버전을 사용했다. Hadoop 2는 Java 7 이상을 지원하므로 Java 8을 선택했다. 마지막으로 공용 설정은 core-site.xml, hdfs-site.xml을 포함하도록 구성할 것이다.

먼저 다음과 같은 디렉토리 구조로 폴더와 파일을 생성한다.

.
└── hadoop
    ├── base
    │   ├── Dockerfile
    │   └── core-site.xml
    ├── namenode
    │   ├── Dockerfile
    │   ├── hdfs-site.xml
    │   └── start.sh
    └── datanode
        ├── Dockerfile
        ├── hdfs-site.xml
        └── start.sh

hadoop의 하위 폴더인 base, namenode, 그리고 datanode 폴더와 그 하위에 다시 위치한 개별 Dockerfile은 각 항목이 이미지로 빌드될 것임을 보여준다.

baes/Dockerfile의 내용을 다음과 같이 작성한다.

# 기반이 되는 이미지를 설정. 여기서는 ubuntu 18 기반인 zulu의 openjdk 8버전을 선택
FROM azul/zulu-openjdk:8

# 바이너리를 내려받기 위해 설치
RUN apt-get update && apt-get install -y curl 

ENV HADOOP_VERSION=2.9.2
ENV HADOOP_URL=http://mirror.apache-kr.org/hadoop/common/hadoop-$HADOOP_VERSION/hadoop-$HADOOP_VERSION.tar.gz

# Hadoop 2.9.2 버전을 내려받고 /opt/hadoop에 압축 해제
RUN curl -fSL "$HADOOP_URL" -o /tmp/hadoop.tar.gz \
    && tar -xvf /tmp/hadoop.tar.gz -C /opt/ \
    && rm /tmp/hadoop.tar.gz

# 데이터 디렉토리 생성 및 설정 폴더의 심볼릭 링크 생성
RUN ln -s /opt/hadoop-$HADOOP_VERSION /opt/hadoop \
    && mkdir /opt/hadoop/dfs \
    && ln -s /opt/hadoop-$HADOOP_VERSION/etc/hadoop /etc/hadoop \
    && rm -rf /opt/hadoop/share/doc

# 로컬의 core-site.xml 파일을 복제
ADD core-site.xml /etc/hadoop/

# 실행 환경에 필요한 환경 변수 등록
ENV HADOOP_PREFIX /opt/hadoop
ENV HADOOP_CONF_DIR /etc/hadoop
ENV PATH $HADOOP_PREFIX/bin/:$PATH
ENV JAVA_HOME /usr/lib/jvm/zulu-8-amd64

기반 이미지인 azul/zulu-openjdk:8는 ubuntu 18 기반이라서 이미지 크기가 315MB로 꽤 크다.
이 크기를 작게 줄이려고 alpine 기반으로 생성해서는 안된다. Hadoop은 일반적인 GNU/Linux 환경에서 동작할 수 있도록 개발되었기 때문이다.

base/core-site.xml은 다음과 같이 작성한다.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://namenode:9000/</value>
    <description>NameNode URI
    </description>
  </property>  
</configuration>

fs.defaultFS 설정은 NameNode 위치를 찾는 중요한 설정으로, DataNode 뿐만 아니라 각종 애플리케이션에서 NameNode에 파일 읽기/쓰기 요청을 할 때 사용되는 항목이다.
URI의 호스트 이름이 namenode로 설정되었는데, NameNode 컨테이너의 호스트 이름을 namenode로 지정할 것이다.

이제 터미널에서 base 디렉토리로 이동해서 baes 이미지를 생성해보자.

cd base
docker build -t hadoop-base:2.9.2 .

현재 위치한 폴더의 Dockerfile을 사용해서 docker 이미지를 빌드하겠다는 명령어이다. Dockerfile을 작성한대로 각 라인이 하나의 빌드 단계가 되어 명렁어를 실행하는 로그가 출력된다.

빌드가 완료되면 다음 명렁어로 로컬에 생성된 이미지를 확인할 수 있다.

docker images

REPOSITORY        TAG                 IMAGE ID            CREATED             SIZE
hadoop-base       2.9.2               fab79eab7d71        2 mins ago          1.2GB

이 이미지는 다음과 같은 이미지 계층 구조를 갖는다. 간단한 구조를 갖지만 이 base 이미지를 통해 모든 Hadoop 컴포넌트의 기반으로 사용할 수 있다.

Hadoop base 이미지 계층그림 1. Hadoop base 이미지 계층 구조. OS → Runtime → App base의 간단한 구조이다.

NameNode

Java와 Hadoop binary를 가지고 있는 base 이미지를 생성했으니, 이제 NameNode 이미지를 생성해보자.
NameNode 구성시 고려해야할 부분은 다음과 같다.

  • FsImage, EditLog를 저장하는 로컬 파일 시스템 경로
  • NameNode용 hdfs-site.xml 설정
  • NameNode 최초 구동 확인 및 네임스페이스 포맷

먼저 hdfs-site.xml 파일을 다음과 같이 작성한다.
dfs.namenode.name.dir은 FsImage, EditLog 파일을 저장하는 경로이다. HDFS 파일 블록 크기를 결정하는 dfs.blocksize 항목은 바이트 수로 여기서는 테스트를 위해 기본 값보다 훨씬 작은 10MB로 설정했다. (기본값은 128MB) 이 외의 항목들은 hdfs-default.xml 파일을 참고한다.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>file:///opt/hadoop/dfs/name</value>
  </property>
  <property>
    <name>dfs.blocksize</name>
    <value>10485760</value>
  </property>
  <property>
    <name>dfs.client.use.datanode.hostname</name>
    <value>true</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-bind-host</name>
    <value>0.0.0.0</value>
  </property>
  <property>
    <name>dfs.namenode.servicerpc-bind-host</name>
    <value>0.0.0.0</value>
  </property>
  <property>
    <name>dfs.namenode.http-bind-host</name>
    <value>0.0.0.0</value>
  </property>
  <property>
    <name>dfs.namenode.https-bind-host</name>
    <value>0.0.0.0</value>
  </property>
</configuration>

시작 스크립트인 start.sh에서는 NameNode의 네임스페이스가 포맷되었는지 확인하고, 포맷되기 전이라면 구동 전 포맷을 먼저 진행해야 한다.
다음과 같이 작성했다.

#!/bin/bash

# 네임스페이스 디렉토리를 입력받아서 
NAME_DIR=$1
echo $NAME_DIR

# 비어있지 않다면 이미 포맷된 것이므로 건너뛰고
if [ "$(ls -A $NAME_DIR)" ]; then
  echo "NameNode is already formatted."
# 비어있다면 포맷을 진행
else
  echo "Format NameNode."
  $HADOOP_PREFIX/bin/hdfs --config $HADOOP_CONF_DIR namenode -format
fi

# NameNode 기동
$HADOOP_PREFIX/bin/hdfs --config $HADOOP_CONF_DIR namenode

Dockerfile은 base 이미지 덕분에 간단하다.

# 방금 전 로컬에 생성한 base 이미지
FROM hadoop-base:2.9.2

# NameNode Web UI 응답 여부를 통해 Healthcheck
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD curl -f http://localhost:50070/ || exit 1

# 설정 파일 복제
ADD hdfs-site.xml /etc/hadoop/

# FsImage, EditLog 파일 경로를 volume으로 연결
RUN mkdir /opt/hadoop/dfs/name
VOLUME /opt/hadoop/dfs/name

# 실행 스크립트 복제
ADD start.sh /start.sh
RUN chmod a+x /start.sh

# NameNode의 HTTP, IPC 포트 노출
EXPOSE 50070 9000

# 시작 명령어 등록
CMD ["/start.sh", "/opt/hadoop/dfs/name"]

이제 이미지를 생성하자. 기본 명령어와 바이너리 파일을 다운로드 받는 등 시간이 오래 걸리는 작업은 이미 base 이미지에서 처리했기 때문에, 그 위에 다시 한번 계층을 쌓는 NameNode는 빌드 시간이 얼마 걸리지 않는 것을 볼 수 있다.

cd namenode
docker build -t hadoop-namenode:2.9.2 .

두 개의 이미지가 생성되었고 계층 구조에 하나의 이미지가 더해졌다.

Hadoop namenode 이미지 계층

NameNode 이미지를 생성했으니 이제 실제로 기동시켜볼 차례이다. 어차피 DataNode 이미지를 생성하면 docker compose를 구성하는 것이 훨씬 간편하므로 바로 compose 설정 파일을 구성하겠다.

먼저 root 디렉토리에 docker-compose.yml 파일을 생성한다. 디렉토리 구조를 보면 아래와 같다.

.
└── hadoop
    ├── base
    ├── namenode
    ├── datanode
    └── docker-compose.yml

설정 파일의 내용을 작성한다. services에는 기동할 컨테이너 정보를, volumes에는 마운트할 volume 정보를, networks에는 컨테이너 간 어떤 네트워크 구성을 사용할지 지정하는 항목이다.
volumes 이하에 정의된 각 항목은 다음과 같은 의미를 갖고 있다.

  • namenode:/opt/hadoop/dfs/namenamenode volume을 컨테이너의 /opt/hadoop/dfs/name 경로에 마운트
  • /tmp:/tmp: 컨테이너가 기동되는 호스트의 /tmp 경로를 컨테이너의 /tmp 경로로 마운트. 호스트와 컨테이너 간 파일을 쉽게 공유하기 위해서 지정함

콜론으로 구분된 설정 값의 뒷 부분이 컨테이너에 해당한다는 것을 기억하면 쉽게 이해할 수 있다.

version: "3"

services:
  namenode:
    image: hadoop-namenode:2.9.2
    container_name: namenode
    hostname: namenode
    ports:
      - "50070:50070"
      - "9000:9000"
    volumes:
      - namenode:/opt/hadoop/dfs/name
      - /tmp:/tmp
    networks:
      - bridge

volumes:
  namenode:

networks:
  bridge:

이제 이 설정 파일을 바탕으로 NameNode 컨테이너를 기동할 수 있다.

# docker-compose.yml 파일이 위치한 경로로 이동
cd hadoop

# 컨테이너를 백그라운드에서 실행
#  종료할 때에는 docker-compose down
docker-compose up -d
Creating namenode        ... done

# 기동중인 컨테이너 프로세스 확인
docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                            PORTS               622e4f642435
hadoop-namenode:2.9.2          "/start.sh /opt/hado…"   10 seconds ago      Up 6 seconds (health: starting)   0.0.0.0.:9000->9000/tcp, 0.0.0.0.:50070->50070/tcp 

# 생성된 bridge 네트워크 확인
docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
0d9989bd9f78        bridge              bridge              local
9ae1ae84360f        hadoop_bridge       bridge              local
62a94ebd58b7        host                host                local

# 생성된 volume 확인
docker volume ls
DRIVER              VOLUME NAME
local               hadoop_namenode

# namenode 컨테이너의 로그 확인
docker logs -f namenode

docker compose로 기동한 후 마지막 명령어로 로그를 살펴보면, 네임스페이스를 포맷한 로그와 NameNode를 기동한 로그를 확인할 수 있다.
브라우저에서 http://localhost:50070 으로 접속하면 아래와 같은 NameNode Web UI에 접근한다.

NameNode Web UI

또한 NameNode가 기동되었으니, 아직 DataNode를 띄우지 않더라도 폴더의 생성과 삭제, 그리고 파일 목록 조회가 가능하다.
NameNode 컨테이너 내부에 있는 Hadoop 클라이언트를 실행해서 테스트해보자.

# namenode 이름의 컨테이너의 hadoop 클라이언트를 실행. 파일 시스템의 root 디렉토리를 모두 조회한다.
docker exec namenode /opt/hadoop/bin/hadoop fs -ls -R /

# 명령어 등록
alias hadoop="docker exec namenode /opt/hadoop/bin/hadoop"

# 폴더 생성/조회/삭제
hadoop fs -mkdir -p /tmp/test/app
hadoop fs -ls -R /tmp
hadoop fs -rm -r /tmp/test/app

docker exec [컨테이너 이름] [명령어]를 입력하면 동작 중인 컨테이너 내에서 [명령어]에 해당하는 명령어를 실행한 결과의 표준 출력을 현재 쉘에 출력한다.
컨테이너 내 자주 실행하는 프로그램응 alias로 등록해두면 편리하다. 여기에서는 NameNode의 bin/hadoop 프로그램을 hadoop으로 alias 지정했다.

DataNode

먼저 작성했던 JVM과 하둡 바이너리를 포함하는 base 이미지로부터 DataNode 이미지를 생성해보자. 고려해야할 부분은 두 가지이다.

  • 파일 블록을 저장하는 로컬 파일 시스템 경로
  • DataNode용 hdfs-site.xml 설정
    파일 블록 저장 경로는 $HADOOP_PREFIX/dfs/data로 설정할 것이다. 이 내용은 hdfs-site.xml 파일을 datanode 디렉토리 이하에 생성하고 내용을 다음과 같이 작성한다.
<configuration>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>file:///opt/hadoop/dfs/data</value>
  </property>
  <property>
    <name>dfs.blocksize</name>
    <value>10485760</value>
  </property>  
  <property>
    <name>dfs.datanode.use.datanode.hostname</name>
    <value>true</value>
  </property>
</configuration>

시작 스크립트는 start.sh에 다음과 같이 작성한다.

#!/bin/sh

$HADOOP_PREFIX/bin/hdfs --config $HADOOP_CONF_DIR datanode

hdfs 프로그램을 datanode 옵션으로 시작하면 DataNode 프로세스가 기동한다.

마지막으로 Dockerfile 이다. HEALTHCHECK에 Web UI 주소가 입력된 것과 EXPOSE에 명시한 포트를 눈여겨 본다.

FROM hadoop-base:2.9.2

# DataNode Web UI 응답 여부를 통해 Healthcheck
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3  CMD curl -f http://localhost:50075/ || exit 1

RUN mkdir /opt/hadoop/dfs/data
VOLUME /opt/hadoop/dfs/data

ADD start.sh /start.sh
RUN chmod a+x /start.sh

# WebUI, 데이터전송
EXPOSE 50075 50010

CMD ["/start.sh"]

NameNode 이미지를 구성할 때와 크게 다르지 않다. 이제 생성한 파일들을 가지고 이미지를 생성한다.

cd datanode
docker build -t hadoop-datanode:2.9.2 .

이제 컨테이너 실행 환경 정보를 담고 있는 docker-compose.yml 파일에 DataNode를 추가한다. 로컬 환경이지만 세 개의 DataNode를 띄울 것이다.

version: "3.4"

# 이미지와 네트워크 정보에 대한 base service를 지정
x-datanode_base: &datanode_base
  image: hadoop-datanode:2.9.2
  networks:
    - bridge

services:
  namenode:
    image: hadoop-namenode:2.9.2
    container_name: namenode
    hostname: namenode
    ports:
      - 50070:50070
      - 9000:9000
    volumes:
      - namenode:/opt/hadoop/dfs/name
      - /tmp:/tmp
    networks:
      - bridge

  datanode01:
    <<: *datanode_base
    container_name: datanode01
    hostname: datanode01
    volumes:
      - datanode01:/opt/hadoop/dfs/data
  
  datanode02:
    <<: *datanode_base
    container_name: datanode02
    hostname: datanode02
    volumes:
      - datanode02:/opt/hadoop/dfs/data

  datanode03:
    <<: *datanode_base
    container_name: datanode03
    hostname: datanode03
    volumes:
      - datanode03:/opt/hadoop/dfs/data

volumes:
  namenode:
  datanode01:
  datanode02:
  datanode03:

networks:
  bridge:

파일을 수정하고 docker-compose up -d를 다시 실행하면 세 개의 DataNode 컨테이너를 추가로 띄우게 된다. DataNode는 NameNode로 heartbeat을 보내면서 NameNode에 등록된다.

Kubernetes Virtual Storage (Ceph) Installation

설치에 필요한 도구로 Rook을 사용할 예정입니다. Rook은 오픈소스 클라우드 네이티브 스토리지 오케스트레이터로, 클라우드 네이티브 환경과 기본적으로 통합할 수 있는 다양한 스토리지 솔루션 세트에 대한 플랫폼, 프레임 워크 및 지원합니다. Rook을 통해 Ceph 가상스토리지를 구성하고 공유 파일 시스템을 적용하도록 하겠습니다.

Rook 구성도

Rook은 쿠버네티스 POD에서 실행되며, Ceph, EdgeFS등 가상솔루션을 POD로 배포하여 관리하는 도구입니다. agent를 통해 Ceph, EdgeFS등 가상솔루션을 관리하고, OSD를 통해 데이터를 영구저장합니다.

/images/2020-01-28-kubernetes-rook-ceph/Untitled.png

Ceph vs EdgeFS

Rook에서 제공하는 가상스토리지는 EgdeFS와 Ceph 외에도 다양하게 지원하지만 안정적인 버전은 아래 두가지만 지원합니다.

  • EdgeFS: 데이터베이스처럼 대용량 스토리지가 필요할때 사용됩니다.
  • Ceph: 공유 확장에 특화되어 있는 스토리지가 필요할때 사용됩니다.

공유나 확장에 특화되어 있는 Ceph를 설치하도록 하겠습니다.

Ceph 스토리지 유형

Ceph는 Block, Object, File 기반으로 데이터를 사용할 수 있습니다. 각 유형에 따라서 사용하는 기능에 차이가 있습니다.

  • Block Stroage: 단일 POD에 storage 제공합니다.
  • Object Storage: 애플리케이션이 쿠버네티스 클러스터 내부 또는 외부에서 액세스 할수있느 데이터를 IO 할수있고, S3 API를 스토리지 클러스터에 노출을 제공합니다.
  • Shared Stroage: 여러 POD에서 공유할 수있는 파일 시스템기반 스토리지입니다.

Shared Storage 구성도

이번에 설치해볼 Shared Storage 구성입니다. Ceph 클러스터에 데이터를 저장하고 Ceph를 통해 POD들과 데이터가 공유가 됩니다.

/images/2020-01-28-kubernetes-rook-ceph/Untitled%201.png

Ceph 설치

테스트 환경

쿠버네티스가 설치된 환경이 필요합니다. 설치방법은 쿠버네티스 고가용성 클러스터 구성 블로그를 통해 설치진행 바랍니다.

OS: ubuntu:18.04
Kubernetes: 1.16.4

Ceph 소스 다운로드 및 POD 배포

Rook은 별도의 설치가 없고 github으로 Ceph, EdgeFS 가상스토리지 솔루션을 쿠버네티스에 배포할 수 있도록 제공하고 있습니다.

$ git clone --single-branch --branch release-1.2 https://github.com/rook/rook.git

아래 경로에 보면 common.yaml, operator.yaml이 있습니다. kubectl 명령어를 통해 배포 합니다.

$ kubectl apply -f rook/cluster/examples/kubernetes/ceph/common.yaml
$ kubectl apply -f rook/cluster/examples/kubernetes/ceph/operator.ymal
$ kubectl apply -f rook/cluster/examples/kubernetes/ceph/cluster.yaml

cluster.yaml을 배포하게 되면 POD 중 OSD가 Running 상태인지 확인이 필요합니다. 변경되는 시간이 약 1 ~ 3 분 정도 소요됩니다.
테스트 환경에 따라 OSD 갯수가 차이가 있을 수 있습니다.

$ kubectl get pod -n rook-ceph

/images/2020-01-28-kubernetes-rook-ceph/Untitled%202.png

OSD Running 상태까지가 ceph 클러스터 구성이 완료되었고, Shared Storage 유형을 적용해보겠습니다.

Shared Storage 유형 적용

아래 명령어를 실행하게 되면 MDS POD가 배포가 됩니다. 약 1 ~ 3분 정도 소요됩니다. Shared Storage 옵션을 변경할 수 있는데 자세한 내용은 ceph-filesystem-crd 통해 확인바랍니다.

$ kubectl apply -f rook/cluster/examples/kubernetes/ceph/filesystem.yaml

StorageClass Driver 적용

StorageClass는 POD에서 Ceph 데이터 풀에 접근하기 위해 사용되는 드라이버입니다. kubectl 명령어를 통해 적용합니다.

$ kubectl apply -f rook/cluster/examples/kubernetes/ceph/csi/cephfs/storageclass.yaml

Shared Storage 확인

정상적으로 적용이 되었는지 확인하는 방법압니다. 아래 결과 처럼 myfs가 생성되어 있습니다.

$ kubectl get CephFileSystem -A

결과)

/images/2020-01-28-kubernetes-rook-ceph/Untitled%203.png

Shared Storage 테스트

kube-registry를 배포하면 PVC, docker-registry POD가 배포됩니다. 컨테이너 내부에 접근하여 /var/lib/registry 디렉터리에 dummy 파일을 생성 하여 다른 POD에서 공유되어 보여지는지 확인합니다.

$ kubectl apply -f rook/cluster/examples/kubernetes/ceph/csi/cephfs/kube-registry.yaml

정리

Rook이라는 도구를 이용해서 Ceph를 설치해보았습니다. Ceph를 관리하려면 러닝커브가 있지만 Rook이라는 도구를 이용해서 Ceph 관리와 쿠버네티스와 연동을 쉽게 할 수 있습니다.

Configuring Kubernetes High Availability Clusters

소개

쿠버네티스는 마스터 노드에 내부적으로 API-SERVER를 가지고 있어 마스터 노드를 통해 워커 노드로 통신이 전달됩니다. 대량에 통신량이 발생하게 되면 마스터 노드는 부하를 많이 받아 장애 발생 가능성이 커지게 됩니다. 마스터 노드를 고가용성 클러스터로 연결하게 되면 통신량을 분산시킬 수 있고, 일부가 마스터 노드에서 장애가 발생시 워커 노드의 운영 시스템에는 영향을 줄일 수 있습니다.

구성 환경

아래 사양으로 총 3대 서버를 준비합니다.

OS: CentOS 7
CPU: 2
RAM: 4
Storage: 100G

구성목표

  1. 마스터 노드 3개를 클러스터구성
  2. 가상 네트워크(weave) 적용
  3. ceph storage 적용

도커&쿠버네티스 설치

CentOS 패키지 업데이트와 방화벽을 정지 및 스왑을 종료합니다.

$ sudo yum update -y
$ sudo systemctl disable firewalld && sudo systemctl stop firewalld
$ sudo selinux disabled
$ sudo setenforce 0
$ sudo iptables piv4 forward
$ sudosudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
$ sudo swapoff -a
$ sudo sed -i '/swap/d' /etc/fstab

운영 환경에서는 아래 포트를 오픈하여 진행합니다.

노드 포트 TCP/UDP
마스터 6443, 2379-2380, 10250, 10251, 10252 TCP
마스터, 워커 6783 TCP
마스터, 워커 6783, 6784 UDP
워커 10250, 30000-32767 TCP
로드 밸런서 26443 TCP

호스트네임 설정

호스트네임은 서로 다르게 지정해야합니다.

$ sudo hostnamectl set-hostname node1

$ sudo hostnamectl set-hostname node2

$ sudo hostnamectl set-hostname node3

도커 설치

도커 레파지토리를 등록하여 yum 으로 설치 합니다.

$ sudo yum install -y yum-utils \
    device-mapper-persistent-data \
    lvm2

$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

$ sudo yum install docker-ce docker-ce-cli containerd.io

$ sudo systemctl start docker

설치 후 daemon.json을 추가하여 cgroupdriver를 systemd 옵션으로 사용할 수 있도록 합니다.

$ sudo cat <<EOF > /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF

$ sudo systemctl daemon-reload
$ sudo systemctl enable docker
$ sudo systemctl restart docker

쿠버네티스 설치

쿠버네티스의 레파지토리 저장소를 등록하여 yum 으로 kubelet, kubeadm, kubectl을 설치합니다.

  • kubeadm: 클러스터 관련 작업시 사용됩니다.
  • kubectl: 클러스터의 서비스 및 pod 관리시 사용됩니다.
  • kubelet: 클러스터 에이전트역할을 합니다.
$ sudo cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg [https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg](https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg)
EOF

$ sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

$ sudo systemctl enable kubelet
$ sudo systemctl restart kubelet

node1, node2, node3에 도커와 쿠버네티스가 설치를 하였다면 아래 명령어를 통해 확인해볼 수 있습니다.

$ sudo docker verison
$ kubectl version

로드밸런서 설치

공식문서에서 사용되고 있는 HAProxy를 사용하도록 하겠습니다.
테스트환경이기 때문에 keepalive및 failover 기능없이 진행하도록 하겠습니다.

노드1에만 haproxy 를 설치하도록 하겠습니다.

$ sudo yum install haproxy -y

haproxy 로드밸런싱 설정

node1 IP의 26443포트로 전달받은 데이터를 node1 ~ node3의 6443 포트로 포워드 시켜줍니다.
라운드로빈으로 순차적으로 접근하도록 하겠습니다.

$ sudo cat <<EOF >> /etc/haproxy/haproxy.cfg
frontend kubernetes-master-lb
bind 0.0.0.0:26443
option tcplog
mode tcp
default_backend kubernetes-master-nodes

backend kubernetes-master-nodes
mode tcp
balance roundrobin
option tcp-check
option tcplog
server node1 <node1 IP>:6443 check
server node2 <node2 IP>:6443 check
server node3 <node3 IP>:6443 check
EOF

$ sudo systemctl restart haproxy

haproxy 확인

해당 포트가 오픈되어 있는지 확인합니다.
포트가 오픈되어 있어도 접근이 안될때는 방화벽을 확인해야 합니다.

netstat -an|grep 26443

클러스터 생성

클러스터 생성할때 –upload-certs, –control-plane-endpoint 플래그를 추가해야 인증서가 자동 배포되고, 마스터 노드 조인 명령어가 출력됩니다.

$ sudo kubeadm init --control-plane-endpoint "<노드1 DNS/IP or LoadBalancer DNS/IP>:26443" \
                --upload-certs \
                --pod-network-cidr "10.244.0.0/16"

config 생성

kubectl 사용하기 위해서는 사용자 디렉토리 하위에 .kube/config 가 필요합니다. kubeadm init 명령어를 진행하고 마지막에 로그를 잘보면 config를 생성하는 명령어가 적혀있습니다.

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

클러스터 연결

노드1에서 클러스터 생성시 kubeadm join 명령어가 출력되는데 –control-plane –certificate-key 플래그 포함하여 명령어를 실행하면 마스터 노드로 연결이 되고, 플래그는 추가하지 않고 사용하게 되면 워커노드로 연결됩니다.

노드2 클러스터 연결

$ sudo kubeadm join 192.168.248.251:26443 --token 06glbc.s0yaqonyajs95ez3 \
    --discovery-token-ca-cert-hash sha256:379ff0daa2cffa3f6581ae25c96aa3d6e4a9af43df92b8d0ac5a4dbb4c7e5547 \
    --control-plane --certificate-key 8eb7fa9a38ca1579c3fb61e0a1106935c4e9dfd81cbad259121f223f0adf555f

config 생성

노드2의 사용자에서도 kubectl 명령어를 사용하기 위해선 config를 생성해야 합니다.

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

노드3 클러스터 연결

노드3에서도 노드2와 동일하게 연결을 진행합니다.

$ sudo kubeadm join 192.168.248.251:26443 --token 06glbc.s0yaqonyajs95ez3 \
    --discovery-token-ca-cert-hash sha256:379ff0daa2cffa3f6581ae25c96aa3d6e4a9af43df92b8d0ac5a4dbb4c7e5547 \
    --control-plane --certificate-key 8eb7fa9a38ca1579c3fb61e0a1106935c4e9dfd81cbad259121f223f0adf555f

config 생성

노드3에서도 동일하게 config를 생성해야합니다.

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

클러스터 구성 확인

노드가 연결이 되었다면 아래 명령어를 실행시 노드가 전부 보여야합니다.

$ kubectl get node

마스터 노드에는 기본설정으로 pod 배포가 안됩니다. taint명령어를 통해 pod 배포가 가능하도록 하겠습니다.

$ kubectl taint nodes --all node-role.kubernetes.io/master-

가상 네트워크(weave) 적용

Calico, Canal, Clilum, Flannel, weave 등 다양한 가상네트워크가 있지만 공식문서에서 제공하는 weave를 적용하도록 하겠습니다.

$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

가상네트워크 적용 확인

최초 클러스터를 진행하게 되면 노드의 상태는 NotReady 입니다. 가상네트워크를 적용하게 되면 약 1 ~ 3분 소요되고 Ready 상태로 변경되게 됩니다. 이것으로 가상네트워크 적용이 완료 되었습니다.

$ kubectl get node

nginx 배포 해보기

nginx pod 3개를 배포하는 명령어입니다.

kubectl run --image=nginx --port 80 --replicas=3 nginx-app

아래 명령어를 통해 nginx-app 배포된 노드를 보면 node1 ~ 3 골고루 배포되어 있는걸 확인할 수 있습니다.

kubectl get pod -o wide

정리

이번에 쿠버네티스 고가용성 클러스터를 서버에 구축해보았습니다. 쿠버네티스 버전 1.6 이후 부터는 인증서배포 자동화, 클러스터 연결하는 방법이 간편하게 변경되었습니다. 이전 버전에서는 클러스터 구성하기위해선 복잡한 과정과 설정파일을 만들어야 했지만 이제는 간단하게 명령어 한줄만 입력하면 클러스터에 연결/해지를 하도록 변경되었습니다. 자유로운 노드 할당은 자원 낭비없이 효율적으로 관리하는데 장점이 될 것으로 보여집니다.

참고문서

Get alarms to Telegram in Grafana

1. 알람 채널 추가

  • Alerting > Notification channels 메뉴를 선택합니다.

    /images/2021-01-26-Common-Grafana-Alert/alert_01.png

  • New channel 을 클릭합니다. /images/2021-01-26-Common-Grafana-Alert/alert_02.png
  • Type 을 Telegram 으로 선택합니다.

    /images/2021-01-26-Common-Grafana-Alert/alert_03.png

    /images/2021-01-26-Common-Grafana-Alert/alert_04.png

    • Name, Default : 모든 알람 받기
    • Include image : 이미지 포함 여부
    • Disable Resolve Message : 해결 알람 받지 않기
    • Send reminders : 알림 상기시키기
    • Telegram API settings (BOT API Token, Chat ID) : 텔레그램에 봇을 추가하여 해당 토큰과 사용자의 챗 ID를 기입

    설정하고 Save 버튼을 눌러서 저장합니다.

  • 추가된 Channel 입니다. /images/2021-01-26-Common-Grafana-Alert/alert_05.png

2. 대시보드 패널에 알람 추가

  • 초당 요청량과 평균 응답속도 패널에 특정 수치로 알람을 설정 해보겠습니다. /images/2021-01-26-Common-Grafana-Alert/alert_06.png
  • 추가 하고싶은 패널의 수정 버튼을 누릅니다. 하단의 Alert 설정에서 Create Alert 버튼을 누릅니다. /images/2021-01-26-Common-Grafana-Alert/alert_07.png
  • 그래프 오른쪽 하트를 위 아래로 드래그하여 알람수치를 조정 할 수 있습니다. /images/2021-01-26-Common-Grafana-Alert/alert_08.png
  • 알람 이름과 규칙을 정합니다.

    Evaluate every 10s For 30s

    30초 동안 10초 마다 체크

  • Conditions은 여러개를 추가 할 수 있습니다.

    WHEN avg () OF query (A, 10s, now) IS ABOVE 400

    패널에 추가된 쿼리 A 수치가 10초 전부터 현재까지 평균 값이 400을 넘는 상태 /images/2021-01-26-Common-Grafana-Alert/alert_09.png

  • 평균 응답속도에 대해서도 알람을 설정하겠습니다.

    Evaluate every 10s For 0

    10초 마다 체크 하도록 설정했습니다.

    WHEN max () OF query (B, 10s, now) IS ABOVE 0.03

    OR max () OF query (C, 10s, now) IS ABOVE 0.03

    쿼리 B, C 중에서 10초 전부터 현재까지 최대값이 0.03초를 넘는 상태에 대해서 알람 설정을 했습니다. /images/2021-01-26-Common-Grafana-Alert/alert_10.png

    Conditions 에는 다양한 값으로 조건을 설정 할 수 있습니다. /images/2021-01-26-Common-Grafana-Alert/alert_10_1.png

3. 알람 확인 및 활용

  • 알림 리스트를 대시보드에 패널로 추가할 수 있습니다. /images/2021-01-26-Common-Grafana-Alert/alert_11.png
  • 대시보드에 알람 및 리스트가 추가된 모습입니다. /images/2021-01-26-Common-Grafana-Alert/alert_13.png
  • Telegram 알람 확인 앞서 Notification Channel 에서 Include image 를 설정하였기 때문에 이미지와 함께 알람이 오게 됩니다.

    초당 요청량은 ‘Evaluate every 10s For 30s’ 30초 동안 10초 마다 확인 하도록 설정 하였기 때문에 PENDING(보류중) 알람이 오지않고 보류 상태가 됩니다.

    평균 응답 속도에는 ‘Evaluate every 10s For 0’ 10초 마다 상태를 확인해서 보내도록 설정하여 보류하지 않고 바로 알람이 오게 됩니다.

    • 초록색 : OK
    • 주황색 : PENDING
    • 빨간색 : ALERTING

    /images/2021-01-26-Common-Grafana-Alert/alert_14.png

  • 알람 설정에서 State history 버튼을 눌러서 상태 히스토리를 확인 할 수 있습니다. /images/2021-01-26-Common-Grafana-Alert/alert_15.png
  • Alerting 메뉴에서 Alert Rules 을 선택하면 알람 설정 수정으로 바로가거나 시작 및 일시중지 제어 할 수 있습니다. /images/2021-01-26-Common-Grafana-Alert/alert_16.png

 

참고 자료

  • https://grafana.com/docs/grafana/latest/alerting/

Configuring Monitoring Dashboards Through Grafana

그라파나?

  • 그라파나는 데이터를 시각화하여 분석 및 모니터링을 용이하게 해주는 오픈소스 분석 플랫폼입니다. 여러 데이터 소스를 연동하여 사용 할 수 있으며 시각화 된 데이터들을 대시보드로 만들 수 있습니다.

    LIVE DEMO

  • 앞서 설치한 그라파나와 프로메테우스의 메트릭 정보를 조회하여 시각화 하는 방법에 대해 알아보겠습니다.

구성 방법

1. 데이터 소스 생성

  • Create a data source 메뉴를 선택합니다. /images/2020-03-17-Common-Dashborad/grafana_1.PNG
  • 데이터 소스로 프로메테우스를 선택합니다. /images/2020-03-17-Common-Dashborad/grafana_2.PNG
  • 프로메테우스 서버 정보를 입력한 후 하단의 Save&Test를 클릭합니다.
    • 연결테스트 후 이상이 없다면 저장됩니다.

/images/2020-03-17-Common-Dashborad/grafana_3.PNG

2. 대시 보드 생성

  • 홈으로 돌아와 Build a dashboard 메뉴를 선택합니다.

/images/2020-03-17-Common-Dashborad/grafana_4.PNG

  • 패널 선택장이 나옵니다. 대시보드는 이 패널들을 구성하고 배치하면 됩니다.
    • 메트릭 조회를 위해 Add Query를 선택합니다

/images/2020-03-17-Common-Dashborad/grafana_5PNG

  • Query 선택창에서 앞에 생성한 Data Source를 불러옵니다.
  • Metric에선 노드익스포터에서 수집한 항목을 선택합니다.

/images/2020-03-17-Common-Dashborad/grafana_7PNG

잠시 돌아와서 위에 선택한 메트릭 항목은 아래와 같은 구조를 가지고 있습니다.
따라서 Metric name으로만 조회시 프로메테우스 서버가 수집한 같은 이름 항목 전부를 조회 합니다. Label name으로 구분하여 조회 할 수 있습니다.
  • Prometheus Metric

/images/2020-03-17-Common-Dashborad/metrics.PNG

  • 이처럼 프로메테우스 서버에서도 메트릭을 조회할 수 있습니다.
  • node_cpu_seconds_total{job=”kube2”,mode=”system”}
    • ex) kube2 host에서 system 영역 cpu 사용률

/images/2020-03-17-Common-Dashborad/grafana_9.PNG

  • 다시 돌아와서 생성한 패널 쿼리에 적용해보겠습니다.

/images/2020-03-17-Common-Dashborad/grafana_10.PNG

  • node_cpu_seconds_total는 계속 누적이 되고 있는 값이기 때문에 rate함수를 사용합니다.
  • rate(node_cpu_seconds_total{job=”kube2”,mode=”system”}[10m])
    • 10분동안 CPU 사용율 변화수치를 초당으로 변환

/images/2020-03-17-Common-Dashborad/grafana_11.PNG

  • CPU 코어의 평균을 구하여 해당 서버의 CPU 평균 사용률을 표시합니다. -avg(rate(node_cpu_seconds_total{job=”kube2”,mode=”system”}[10m])) by (job)

/images/2020-03-17-Common-Dashborad/grafana_12.PNG

  • 설정에서 그래프 종류를 선택할 수 있습니다.

/images/2020-03-17-Common-Dashborad/grafana_6.PNG

이처럼 자신의 필요한 메트릭 정보를 집계하여 패널로 만든 후 대시보드를 구성하면 됩니다.

외부 대시보드 포맷 사용

  • 매트릭 정보를 직접 집계하여 사용하거나 필요한 데이터를 정의하는게 나름 번거로운 작업이라 그라파나 홈페이지에 다른 여러 사용자들이 구성해놓은 대시보드 포맷을 사용하면 더 쉽게 대시보드를구현할 수 있습니다.

https://grafana.com/grafana/dashboards

/images/2020-03-17-Common-Dashborad/grafana_13.PNG

  • import 화면에서 다운받은 JSON 파일을 upload하거나 COPY ID를 입력하여 적용합니다.

/images/2020-03-17-Common-Dashborad/grafana_14.PNG

결론

프로메테우스, 그라파나를 통해 비교적 쉽게 모니터링을 위한 프로세스들을 만들 수 있었습니다. 여러 익스포터를 통해 필요한 매트릭 수집을 확장할 수 있다는게 큰 장점인 것 같으며 PULL 방식이라 부하에 따른 장애나 성능감소를 걱정하지 않아도 된다고 합니다. 그라나파를 통해 매트릭 데이터를 보기 쉽게 만들 수 있었으며 다양한 데이터 소스를 지원하는 만큼 여러 분야에서 활용하면 좋을 것 같습니다.