'분류 전체보기'에 해당되는 글 48건

  1. 2019.01.17 SpringBoot2 OAuth2 구현과 LDAP 연동
  2. 2019.01.17 [웹보안] 로컬 환경 셋팅과 툴 설치 (1)
  3. 2019.01.16 [카프카(Kafka)] 성능 관련 고찰 (3)
  4. 2019.01.16 Docker : 기초 편 (2)
SpringSecurity OAuth2 이용해 인증서버를 구현해서 운영하려고 보면 여러가지 커스터마이징이 필요하게 된다. 중에서 인증정보를  LDAP 서버에서 받아오는 방식에 대해서 다루어 보려고 한다.

일반적으로는 인증정보는 DB에 저장되어 있고  가져온다. 하지만 동일한 인증정보를 다른 서비스에서 가져가야 할때, 해당 서비스와 DB를 연동하기 어려울 때가 있다. 레드마인이나 이메일 등 만들어진 서비스의 경우 그러하다. 이를 해결하기 위해 대부분의 서비스들은 LDAP 인증을 지원한다. 인증정보가 담긴 곳 앞에 LDAP 서버를 두고 모든 서비스가 LDAP 서버와 연동이 되면 일괄적인 인증정보 관리가 되기 때문에 편리해 진다.

LDAP은 엄밀히 이야기해서 프로토콜이다. 이 프로토콜을 지원하는 서버들이 몇가지 있지만 일반적으로 사용되는건 OpenLDAP 이다. 이 곳에서 OpenLDAP 설치는 별도로 다루지 않는다.

OpenLDAP 이란?



Spring Boot 에 OAuth2 인증 서버 만들기

우선 간단하게 SpringSecurity OAuth2 인증서버를 구성하고, 여기에 LDAP 서버를 연동하는 방법을 설명한다. LDAP 연동을 위한 OAuth2 구현이기 때문에 간략하게 다룬다. 이대로 OAuth2 구현한다면 매우 위험할수 있으므로 OAuth2 구현은 다른곳을 참조하자.

최종적으로 사용된 소스는 이 곳에서 확인 가능하다.


1. 라이브러리 버전 선택

Spring Boot 2 버전 부터 SpringSecurity 를 이용하는 방식이 바뀌었다.


OAuth 2.0 Supports

Functionality from the Spring Security OAuth project is being migrated to core Spring Security. OAuth 2.0 client support has already been added and additional features will be migrated in due course.

If you depend on Spring Security OAuth features that have not yet been migrated you will need to add org.springframework.security.oauth:spring-security-oauth2 and configure things manually. If you only need OAuth 2.0 client support you can use the auto-configuration provided by Spring Boot 2.0. We’re also continuing to support Spring Boot 1.5 so older applications can continue to use that until an upgrade path is provided.

인터넷 상의 대부분의 예제가 SpringBoot 1.x 버전을 대상으로 다루고 있는데, @EnableOAuth2Sso 등의 어노테이션을 이용한다. 하지만 SpringBoot2 에서는 기본적으로 EnableOAuth2Sso 어노테이션을 지원하지 않는다. 이를 사용하려면 구버전과 호환되는 SpringSecurity 버전을 사용해야 한다.

이런 방식을 사용하지 않고 @EnableAuthorizationServer, @EnableResourceServer 어노테이션을 사용하는 SpringBoot2 에 맞춰진 방식으로 구현하였다.


2. Maven Dependencies


  org.springframework.boot
  spring-boot-starter-parent
  2.0.1.RELEASE
  


.
.
.

  
      org.springframework.cloud
      spring-cloud-security
      RELEASE
  
  

SpringBoot 2.0.1 버전을 사용하였다.
SpringSecurity를 추가하기 위해 spring-cloud-security 디펜던시를 추가하였다. SpringBoot 1.x 버전과 호환되지 않으므로 주의하여야 한다.


3. OAuth2 구현

OAuth2 구현에 필요한 클래스들의 기능을 간략하게 정리해보았다. 실제 소스는 깃헙링크를 참조하면 된다.

[AuthorizationServerConfig]
인증 처리를 담당한다.

[ResourceServerConfig]
권한처리를 담당한다.

[SecurityConfig]
인증정보를 가져오는 곳을 설정한다.
이곳에서는 DefaultUserDetailsService 의 구현에 따라 인증정보를 가져온다.

[DefaultUserDetailsService]
테스트 용도로 인증정보를 넣어두었다.

정상적으로 동작을 한다면 아래와 같은 요청과 응답이 온다.

[Request]
curl -X POST \
 http://localhost:8080/oauth/token \
 -u test-client:test-secret \
 -H 'content-type: multipart/form-data' \
 -F username=gaecheok@test.com \
 -F password=1234 \
 -F grant_type=password

[Response]
{
   "access_token": "e51b8482-ffeb-437b-9fa4-765833c44661",
   "token_type": "bearer",
   "refresh_token": "de1b49c5-1213-4247-8709-ef1fc602596b",
   "expires_in": 3599,
   "scope": "read write trust"
}

OAuth2 구현은 LDAP 연동을 위해 간략하게 적용하였다. 다시한번 강조하지만 테스트 용도 외의 사용은 위험하니 주의하여야 한다. OAuth2 에 대한 구체적인 구현은 다른곳을 참조하여서 작성하도록 하자.



SpringSecurity의 인증정보를 LDAP으로 연동하기

1. Maven Dependencies 추가

SpringSecurity 의 LDAP 라이브러리를 추가한다.

   
       org.springframework.security
       spring-security-ldap
       5.0.3.RELEASE
   


2. LDAP 권한 처리 클래스 생성

[LdapAuthoritiesPopulator]
권한을 강제로 할당하도록 구현하였다. 이렇게 처리하면 사용자에게 ROLE_ADMIN 이라는 권한이 부여된다.
실제 서비스에서는 DB, 혹은 LDAP 서비스 내에 있는 사용자에 맞는 권한 정보를 가져와서 authorities 객체에 권한정보를 추가해 주어야 한다.

public class LdapAuthoritiesPopulator implements org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator {
   private DefaultUserDetailsService userService;

   public LdapAuthoritiesPopulator(DefaultUserDetailsService userService) {
       this.userService = userService;
   }

   @Override
   public Collection getGrantedAuthorities(
           DirContextOperations userData, String username) {

       Collection authorities = new HashSet<>();
       authorities.add(new SimpleGrantedAuthority("ADMIN"));

       //userService 와 연계된 DB 등 에서 권한정보를 가져다가 이곳에서 리턴해주면 됨.
       //authorities.addAll(userService.getAuthorities(username));

       return authorities;
   }
}


3. LDAP 서버를 바라보도록 설정

[SecurityConfig]
기존에는 DefaultUserDetailsService 에서 인증정보를 가져왔지만, auth.ldapAuthentication()을 이용하여 인증정보를 LDAP 에서 가져오도록 설정한다.
권한정보를 가져올수 있도록 LdapAuthoritiesPopulator를 정의한다.

@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
   //auth.userDetailsService(userDetailsService);

   auth.ldapAuthentication()
           .ldapAuthoritiesPopulator(new LdapAuthoritiesPopulator(userDetailsService))
           .userDnPatterns("uid={0}")
           .contextSource()
           .url("ldap://192.168.1.1:389/dc=n,dc=co.kr")
           .managerDn("cn=admin,dc=n,dc=co.kr")
           .managerPassword("secret");
}

LDAP 접속 정보에 맞게 입력해준다.
일반적으로는 URL, ManagerDn, ManagerPassword 가 필요하고, 경우에 따라 userDN 등이 필요하다.
OpenLDAP 을 설치하였다면 위와 비슷한 내용으로 구성이 된다.



4. 연동확인

auth.ldapAuthentication() 구현이 완료되면 이제 사용자가 접속할 때, 사용자의 아이디-비번을 LDAP 쪽에 전달해 맞는지 여부를 가져오게 된다.
인증정보가 맞다면 권한정보를 가져오기 위해 userDetailsService 를 사용하고, 틀리다면 401 이 리턴된다.


여기까지 LDAP 연동을 살펴보았다. 


실제 운영을 하게 된다면 이 연동 외에도 다양한 요구사항이 있을 수 있다. 

겪었던 요구사항 중 한가지가 OpenLDAP 과 별도의 인증DB 에서 인증정보를 가져오는 것이었다. OpenLDAP이 바라보는 저장소의 인증은 글로벌하게 사용하고, 별도의 인증DB에서는 LDAP 쪽 과는 별개의 계정을 등록해서 사용하기 위함이었다.

user1 이라는 사용자가 로그인 했을때, DB에서 확인하고 없으면 LDAP 에서 확인하도록 구현이 필요했다.

이때는..

userDetailsService 에서 디비에서 인증정보를 가져오도록 구현 한 후,
위에 SecurityConfig 에서    auth.ldapAuthentication() 과 auth.userDetailsService(userDetailsService) 이것을 2개다 설정하면 된다.
이렇게 설정한다면 DB에서 먼저 사용자 인증을 확인하고 있으면 그대로 권한 정보를 가져오고, 없다면 LDAP에서 동일하게 인증과정을 진행을 한다.


Posted by panpid

댓글을 달아 주세요

INTRO


이 글에서는,
웹보안을 공부하고 해킹을 실습해 볼 수 있는 툴을 알아보고 설치 방법을 간단히 안내 하고자 합니다. 

사실 웹보안 시리즈를 연재하고자 마음을 먹고서는, 개요부터 쭉~ 한번 훓고 가려 했는데요.
개요 작성에는 시간이 좀 더 필요할 것 같아서, 바로 본론으로 들어갑니다. 중간에 틈이 나면 전반적인 개요을 한번 다뤄볼까 합니다.


미리 말씀드리자면, 개요에서는 웹 보안의 중요성이나 해킹사례, OWASP Top 10과 같은 국제적 참고자료와 웹 보안 관련한 국내 현황과 법률 사항 등 전반의 내용을 다룰 예정입니다.


사실 과거(2006년)에 웹 보안 글을 몇개 끄적인 적이 있습니다.  당시에서 큰 보부를 가지고 웹보안 전반을 다룰려고 했으나, 그러질 못했네요.


이번에는 인생의 숙제(?)라 생각하고 웹 보안 전반을 다뤄보고자 합니다. 


과거 글들은 아래 링크를 참고하세요.(지금 다시 보니 글에 미숙한 점이 많이 보이네요 ^^;)



자 이제 본론으로 들어갑니다.


저의 개발 환경은 '64bit 윈도우 10 Pro' 환경입니다. 

이 글에서 소개하는 툴들은 다른 환경(Linux, OS X)에서도 동작가능합니다. 다만 여기서는 윈도우 환경만 설명합니다.


많은 툴들이 있겠지만, 여기서는 앞으로 제가 진행할 웹 보안 Article에서 사용될 몇 가지에 대해서만 알아봅니다. 만일 여기서 소개되지 않은 툴을 제 글에서 다룬다면, 툴 설명을 별도로 추가하겠습니다.


참고로 이 글에서는 설치 과정을 세세하게 설명하지는 않습니다. 설치와 관련된 사항은 이미 인터넷에 많은 자료가 있으니 참고 바랍니다. 물론 그럼에도 설치 문제를 해결하지 못한 경우 편하게 댓글로 문의 주세요.


좋은 도구는 높은 생산성과 직결합니다. 아래 소개한 도구를에 익숙해지길 바랍니다.


-----------------------------------------------------------------------------------------------------------------------------------------


1. XAMPP (Cross-platform Apache, MariaDB, PHP, Perl)


XAMPP는 APM(Apache, PHP, MySql) 환경구축을 한번에 할 수 있도록 하는 패키지 프로그램이다.


아래 소개할 DVWA 웹사이트가 PHP와 MariaDB로 구현되어 있는데, 이 사이트를 로컬 PC에서 구동하기 위해 APM 환경이 필요하다.


1.1 XAMPP 다운로드 및 설치

아래 사이트로 가서 XAMPP 설치파일을 다운로드 받는다.


www.apachefriends.org


각 OS 별로 설치 프로그램을 제공하는데, 필자의 경우 현재 시점의 최신 버전의 윈도우용 설치파일을 받아서 설치했다.


(현재 시점 최신 버전) XAMPP for Windows 7.3.0 (PHP 7.3.0)


다운받은 파일을 기본 설정으로 하고 '다음 > 다음 ..' 하여 설치한다.


(설치 과정중 Select Components 단계에서, 불필요한 환경을 제외할 수 있다. 필자 역시 Apache, MySQL, PHP외에 불필요한 것은 설치에서 제외 시켰다. 그리고 설치 경로를 기억해 두자. 기본값으로 설치했다면 'C:\xampp' 일 것이다)



1.2 XAMPP Control Panel 을 통한 서비스 제어

XAMPP 설치가 완료되면 XAMPP Control Panel이라는 관리패널이 실행된다. XAMPP Control Panel은 서비스들을 컨트롤 할 수 있는 관리 기능을 제공하는 프로그램이다. 


(참고로 XAMPP Control Panel이 실행되면 윈도우 트레이 아이콘에 자동 추가 되므로 창을 닫아도 프로그램이 종료되는 것은 아니다. 프로그램을 종료하려면 트레이 아이콘을 우측 클릭하여 Quit 하면 된다.)


(또한 XAMPP Control Panel 프로그램을 종료(quit)한다고 해서 Apache나 MySQL이 같이 종료되는 것은 아니다. 이 프로그램은 말 그대로 편의성을 위해 별도로 제공되는 GUI 기반 프로그램일 뿐이다)



위 화면에서 보는바와 같이, Apache와 MySQL을 구동(Start)시키자.


브라우저에서 http://127.0.0.1 로 접속해보자. 다음 그림과 같이 XAMPP 대시보드가 로딩된다면 성공적이다.





1.3 설치 및 구동 실패 해결

설치 과정이나 설치 후 Apache, MySQL을 구동 시킬때 제대로 동작하지 않는 경우가 종종있다. 

이는 대부분 XAMPP가 사용하는 포트와 서비스가 충돌되기 때문이다.



1.3.1 아파치 구동 실패

Apache 웹서버의 경우 기본 80포트를 사용하는데, 이미 로컬 PC에 80포트가 사용되고 있는 경우 Apache 웹 서버를 시작할 수 없다. 

(필자의 경우에도 로컬 PC에 IIS 웹서버가 동작중인데 80포트를 사용하는 사이트가 있어서 포트를 변경하였다.)


80 포트를 이용하는 서비스를 찾아서 포트를 변경하던지 해당 서비스를 중지 시키던지 한다. 다음 명령어를 통해 현재 로컬 PC의 포트와 서비스 PID를 확인할 수 있으니 참고하자.


netstat -ano


(XAMPP Control Panel 에서도 바로 포트를 확인할 수 있도록 기능을 제공한다. 관리 패털의 우측 상단에 있는 'Netstat' 버튼을 클릭하면 포트와 PID 확인이 가능하다.)



1.3.2 MySQL 구동 실패

로컬 PC에 MySQL이 이미 설치되어 있는 경우, path 관련 오류(MySQL Service detected with wrong path)가 나면서  MySQL이 구동되지 않을 것이다. 될수 있으면 기존 설치된 MySQL을 제거하는 것이 가장 단순한 해결 방법이다.


관리자 계정으로 cmd(명령프롬프트)를 실행하고 다음의 명령어로 해당 MySQL을 제거하면 된다.
(기존 MySQL에 있는 오브젝트들은 미리 백업 받아 두는 것이 좋다)


sc delete mysql 

만일 기존에 설치된 MySQL과 XAMPP의 MySQL을 동시에 같이 사용하고 싶을 경우, 다음의 글을 참고하자. (포트와 서비스 명을 서로 다르게 하여 두개의 MySQL 인스턴스를 띄우는 방식이다.)


http://emjaywebdesigns.com/xampp-and-multiple-instances-of-mysql-on-windows/




1.4 DVWA를 위한 XAMPP 셋팅


1.4.1 dvwa 데이터베이스 생성

XAMPP 웹(http://127.0.0.1)에 접속하여 상단의 phpMyAdmin 메뉴로 이동한다.


phpMyAdmin은 웹으로 MySQL을 관리할 수 있는 프로그램이다. 상단의 '데이터베이스' 메뉴로 이동하여 dvwa라는 이름으로 새 데이터베이스를 만든다.





1.4.2 php.ini 파일 수정


'C:\xampp\php\php.ini' 파일에서 다음 값이 Off로 되어 있다면 On으로 변경하고 저장한다


allow_url_fopen=On

allow_url_include=On


이 설정이 필요한 이유는, dvwa 사이트에서 url include을 사용하기 때문이다.  Apache 웹서버를 재기동 하면 변경된 설정 값이 반영된다.




2. DVWA(Damn Vulnerable Web Application)


DVWA는 그 약자에서도 알 수 있듯이 의도적으로 취약하게 만든 웹 사이트이다. 


보통 웹해킹을 공부하고 직접 시도해 볼려면 여의치가 않다. 임의의 공개된 사이트에 테스트로 해킹을 시도 했다가는 법률적 제재를 받을 수도 있다.그렇다고 직접 개발하기도 만만치가 않다.


DVWA는 PHP/MySQL 기반으로 제작된 웹 애플리케이션으로, 웹 해킹 기술을 직접 실습하고 공격 대응 방안을 학습하기 위한 목적으로 제작되었다.

다음은 DVWA 사이트에서 발췌한 설명이다.


DVWA (Damn Vulnerable Web App)는 PHP / MySQL 웹 애플리케이션으로 취약합니다. 주요 목표는 보안 전문가가 법률 환경에서 자신의 기술과 도구를 테스트하고 웹 개발자가 웹 응용 프로그램을 보호하는 과정을 더 잘 이해할 수 있도록 지원하고 교사 / 학생이 강의실 환경에서 웹 응용 프로그램 보안을 가르치고 배우도록 돕는 것입니다 .




2.1 DVWA 다운로드 및 설치

아래 주소로 이동하여 DVWA-master.zip 파일을 다운로드 받는다


http://www.dvwa.co.uk/


다운 받은 파일의 압축을 풀고 DVWA-master 폴더의 하위 내용물들을 모두 다음의 위치로 옮긴다.


C:\xampp\htdocs\dvwa


(XAMPP 웹으로 접속 가능하도록 htdocs 폴더 하위에 dvwa라는 이름의 폴더를 생성하여 그 아래로  DVWA-master 폴더 내용을 이동(or 복사) 한다.)


파일들이 정상적으로 이동되었다면, 다음의 주소로  dvwa 사이트에 접속할 수 있다.


http://127.0.0.1/dvwa


위 주소로 최초 접근하면 다음과 같은 Setup 화면이 나오고 추가 설정을 해 줘야 한다.



여기서 빨간색으로 나온 부분을 모두 잡아줘야 사용이 가능해 진다. reCAPTCHA key 가 설정되지 않아서 빨간색으로 표시되어 있다. 키를 발급 받는 방법을 알아보자.



2.2 reCAPTCHA key 발급 받기

DVWA에서 캡챠 관련 공격을 테스트 하기 위해 필요한 설정이다. reCAPTCHA 키를 받기 위해서 다음의 주소로 접속한다.


www.google.com/recaptcha/admin


구글 계정으로 로그인해야 키 발급이 가능하다. 로그인 후 다음 그림과 같이 입력하고 폼을 제출한다.



폼을 제출하면 Site Key와 Secret key가 생성된다. 이 두 키 값을 dvwa 설정 파일에 등록해야 한다.



2.3 설정 파일 수정

먼저 config 폴더에 있는 config.inc.php.dist 파일 이름에서 '.dist'을 제거한다.


config.inc.php.dist --> (파일명 변경) --> config.inc.php




2.3.1 reCAPTCHA key 설정

config.inc.php 파일을 열어서 다음의 내용을 설정한다. 앞서 발급받은 key들을 다음과 같이 알맞게 지정한다.


$_DVWA[ 'recaptcha_public_key' ]  = '(Site Key 값 입력)';

$_DVWA[ 'recaptcha_private_key' ] = '(Secret key 값 입력);




2.3.2 DB 접속 패스워드 수정

config.inc.php 파일의 DB 패스워드를 다음과 같이 패스워드를 공백으로 변경한다.


$_DVWA[ 'db_password' ] = '';


이제 dvwa 설정이 완료되었다. 앞서 접속한 dvwa 설정화면을 새로고침 해보면 reCAPTCHA key 가 녹색으로 표시된것을 확인할 수 있다.



2.4 데이터베이스 생성

마지막으로 dvwa 데이터베이스에 관련 오브젝트들을 생성한다. 


설정화면에서 'Create / Reset Database' 버튼을 클릭해서 관련 테이블등을 생성하자. dvwa로 해킹 실습을 해 보다가 데이터를 초기화 하고 싶으면 언제든이 Reset 할 수도 있다.




2.5 DVWA 사이트 접속

이제 DVWA를 위한 모든 설정이 완료되었다. http://127.0.0.1/dvwa/ 로 접속하여 사이트를 확인해 보자.


로그인 창이 뜨면 admin / password로 입력한다. 다음 그림과 같이 DVWA 사이트를 확인할 수 있다. 사이트를 한번 쭉 훓어 보기 바란다.





3. Burp Suite 설치

웹 사이트 테스트 및 해킹 용도로 자주 사용되는 웹 프록시 프로그램이다.웹 요청을 프록시를 경유하도록 만들어서, 중간에 패킷을 가로채어 조사하고 변조해 볼 수 있다. Burp Suite는 프록시 기능을 넘어, 실제 웹 해킹을 자동화 해서 수행할 수 있는 기능도 제공한다.


유료와 무료 버전이 존재하며 우리는 무료인 커뮤니티 버전을 설치한다.



3.1 Burp Suite 다운로드 및 설치

아래 주소로 이동하여 커뮤니티 버전의 설치 파일을 다운로드 받아서 설치한다.


https://portswigger.net/burp/communitydownload



3.2 브라우저 프록시 설정


3.2.1 프록시 설정 확인

Burp Suite는 기본 8080 포트로 프록시 역할을 수행한다. 


다음 그림은 Burp Suite를 실행해서 Proxy 옵션을 확인하는 화면이다. 여기서 프록시 리스닝 포트를 변경할 수 있지만 여기서는 기본값을 사용한다.





3.2.2 브라우저에 프록시 설정하기

필자가 사용하는 구글 크롬 브라우저를 기반으로 프록시 설정을 알아본다. 크롬 브라우저의 설정화면으로 이동한다. 


상단의 '설정 검색'에서 '프록시' 라고 검색한다. 


'프록시 설정 열기'를 하여 LAN 설정에서 프록시 서버 사용을 활성화하고 IP(localhost)와 포트(8080)를 입력한다.





이렇게 브라우저에 프록시가 설정되면, 이제부터는 모든 웹 요청과 응답은 이 프록시를 경유하게 된다.


* 주의

웹 해킹을 실습하지 않을 때는 프록시 서버를 비활성화 시켜 놓는 것이 좋다.

그렇지 않으면 일반 사이트 접속이 원활하지 않을 수 있다.



이로써 기본적인 툴 설치와 환경 설정이 완료 되었다. 이제부터 본격적으로 웹보안 공부를 시작해 보도록 하자



수고 하셨습니다~~~~~~~~~~~~~~~~



Posted by 사용자 박종명

댓글을 달아 주세요

  1. 도와주세요 2020.10.08 03:18  댓글주소  수정/삭제  댓글쓰기

    혹시 2.4에 빨간색으로 allow_url_fopen=on, allow_url_include=on 오류뜬거 어떤방법으로 해결했는지 알수있을까요???


사내 시스템의 임시버퍼 용도로 Redis를 도입하여 성능 테스트를 진행하던 중, 버퍼 용량 이슈로 인하여 Redis와 Kafka를 비교하게 되었다. 

우선 결론적으로는 Redis(List)와 Kafka 사용 시 성능 차이는 거의 없었고, Kafka가 보관 용량에 대해선 유리하였다.


이번 주제에서는 Kafka 성능에 대한 정리이므로 Redis & Kafka 비교는 나중에 진행하기로 한다. 

궁금증

Kafka는 대용량 메시지 처리 성능이 좋다고 조금만 리서치 해보면 알 수 있다. 그러면.... 

처리량이 얼마나 될까? 

HDD와 SSD는 차이가 발생할까? 

Producer와 Consumer 수에 따라서 성능 차이가 날까?  

여러 Consumer Group이 같은 토픽을 조회해도 성능 차이가 없다고 하던데 과연 그럴까?

이러한 궁금증이 생겼다.


가장 궁금한 부분은 HDD와 SSD 성능 차이였다. 

어떤 블로그에서는 HDD보다 SSD가 최대 2.7배 성능이 높다고 하고, 어떤 학술 논문집에서는 차이가 거의 없다고 한다.

이번 성능 테스트를 진행하면서 알아보려 한다.


테스트 케이스

  • 하드웨어 스펙 차이에 따른 성능 비교 (CPU, Memory, SSD, HDD)
  • 브로커 증가에 따른 성능 비교
  • Producer 및 Consumer 수에 따른 성능 비교
  • Consumer Group 수에 따른 성능 비교

테스트 환경, 스펙, 설정

테스트 환경 구성

  • Zookpeer 3노드
  • Kafka 6노드
  • Test 장비 4노드

Zookeeper 스펙

클라우드

Azure 표준 F2s

CPU

2Core 

Memory 

4GB 

스토리지 

SSD 32GB(120 iops)

 Bandwidth

 1.5GbE

OS

CentOS Linux release 7.5.1804

Java

java(TM) SE 10.0.1

버전

kafka_2.11-2.0.0

Kafka 스펙

클라우드

Azure 표준 F4s

Azure 표준 F8s

CPU

4Core 

 8Core

Memory 

8GB 

16GB 

스토리지 

HDD 1024GB(500 iops) VS SSD 1024GB(5000 ipos)

Bandwidth

 10GbE

OS

CentOS Linux release 7.5.1804

Java

java(TM) SE 10.0.1

버전

kafka_2.11-2.0.0

 Heap Memory

 Xmx6G -Xms6G

 Xmx10G -Xms10G

토픽 및 파티션 구성

하나의 물리적 노드 당 하나의 파티션으로 정의한다. 

예를 들어 5개의 노드를 사용하는 토픽은 5개의 파티션을 가지고 있다. 

추가로 정확한 throughput을 측정하기 위해 복제는 사용하지 않았다. 


테스트 툴 선택

Kafka는 자체적으로 테스트 툴을 제공하고 있다.

응답시간을 지원하지 않으므로 테스트 평가 기준은 초당 처리량(MB/sec)으로 정의한다. 

아래와 같이 producer, consumer 별로 테스트를 진행하였다. 

 구분

테스트 명령어 

설명 

producer 

 ./kafka_2.11-2.0.0/bin/kafka-producer-perf-test.sh \

--topic test \

--record-size 1000 \

--num-records 20000000 \

--producer-props \

bootstrap.servers=10.10.20.14:9092...... \

--throughput 1000000

topic : 토픽이름

record-size : 테스트 레코드 사이즈(byte) 

num-records : 생성할 메시지수

producer-prop : 프로듀서 옵션 처리

bootstrap.servers : 브로커 리스트

throughput : 최대 메시지 처리량 제한(초당 몇개의 메시지)

 consumer

 ./kafka_2.11-2.0.0/bin/kafka-consumer-perf-test.sh \

--topic test \

--show-detailed-stats \

--group test_group \

--broker-list 10.10.20.14:9092...... \

--reporting-interval 500 \

--messages 1000000

topic : 토픽이름

messages : 소비할 메시지 개수

show-detailed-stats : 통계 지표 리포트

group : consumer group 

broker-list : 브로커 리스트

reporting-interval : 리포팅 간격

kafka 설정

6노드 모두 아래와 같이 동일하게 설정하였다.


...

num.network.threads=3

num.io.threads=8

socket.send.buffer.bytes=102400

socket.receive.buffer.bytes=102400

socket.request.max.bytes=104857600


num.partitions=1 #기본 파티션 개수

num.recovery.threads.per.data.dir=1

offsets.topic.replication.factor=1 #기본 복제 개수

transaction.state.log.replication.factor=1 

transaction.state.log.min.isr=1


log.retention.hours=168 #토픽 보관시간 

log.segment.bytes=1073741824 

log.retention.check.interval.ms=300000




테스트 결과

하드웨어 스펙 차이에 따른 성능 비교

Producer 테스트 (Test 토픽 6 파티션 기준)

  • 1개의 Producer일 경우 스토리지(SSD, HDD) 및 하드웨어 스펙(F4s, F8s) 상관없이 동일한 처리량을 보여준다.
  • F4s 스펙에서는 n개의 Producer가 늘어나면,  처리량은 1/n로 나눠진다. (전체 처리량 같음)
  • F8s 스펙에서는 n개의 Producer가 늘어나더라도 처리량은 1/n 나뉘지 않고 더 높은 성능을 보여준다. (전체 처리량 많아짐)

Comsumer 테스트 (Test 토픽 4 파티션 기준)

  • 1개의 Consumer일 경우 SSD가 HDD보다 약 2.4배 빠르다.
  • F4s , F8s 스펙에서는 성능 차이가 크지 않았다.
  • n개의 Consumer가 늘어나면, SSD 환경 처리량은 1/n으로 나뉘지 않고 더 높은 성능을 보여준다. (전체 처리량 많아짐)
  • n개의 Consumer가 늘어날 경우 HDD 환경 처리량은 1/n으로 나눠진다. (전체 처리량 같음)

하드웨어 사용률

1개의 Producer, Consumer 기준으로 하드웨어 사용률을 확인해 보았다.

Producer는 사용률이 높고, Consumer는 낮다.

 구분

하드웨어 사용률 (HTOP) 

Producer 

 



Consumer

 



결론

 구분

결과 

producer 

Producer가 늘어날수록 하드웨어 사용량이 많아 처리량은 줄어든다. 하드웨어 스펙을 올리면 더 높은 성능을 보여준다.

SSD vs HDD 비교에서 하드웨어 스펙이 낮으면 차이가 별로 없고, 높으면 차이가 난다.(측정 오류 발생 소지)

 consumer

Consumer가 늘어날수록 전체 처리량의 차이는 SSD 많아지고 HDD는 거의 없다..

SSD와 HDD의 처리량은 약2.3배 차이가 난다.

SSD에 비해서 성능 차이가 있을 뿐이지 HDD도 성능이 엄청 좋다. 
HDD 기준 전체처리량은 Producer 초당 10~12만 메시지(1kb)를 적재, Consumer는 초당 22~24만 메시지를 소비한다. 

브로커 수에 따른 성능 비교

테스트 환경은 Azure F4s, SSD에서 진행하고, 브로커가 1 증가하면 파티션도 1 증가한다. 
예를 들어 4 브로커면 테스트 토픽의 4개의 파티션이라고 생각하면 된다. 

Producer 테스트

  • 브로커가 늘어나면 Producer 처리량도 같이 증가
  • 4 브로커 이상에서는 처리량 변화가 없음

Consumer 테스트 (같은 Consumer Group 기준)

  • 브로커가 증가하면 Consumer 처리량도 같이 증가

브로커 수에 따른 처리량 그래프

브로커 수에 따른 결론

브로커가 늘어나면 Producer나 Consumer 모두 처리량이 같이 증가한다. 


브로커 1노드 기준 최대  처리량

스토리지 타입

 1 Producer

 1 Consumer

 hdd

 쓰기 45~52MB/sec

(55649 records/sec)

 읽기 250~260MB/sec

(262208 records/sec)

 ssd

 쓰기 100~110MB/sec

(117094 records/sec)

 읽기 250~260MB/sec

(264654 records/sec)

여러 브로커 기준 최대  처리량

스토리지 타입

 1 Producer

 1 Consumer

 hdd

 쓰기 190~200MB/sec

(206745 records/sec)

 읽기 600~700MB/sec

 ssd

 쓰기 195~200MB/sec

(206582 records/sec)

 읽기 600~700MB/sec




Producer 및 Consumer 수에 따른 성능 비교

이전 테스트의 결과를 보면 확인할 수 있다. 

Producer 및 Consumer 수에 따른 결론

하드웨어 스펙이 좋으면 Producer, Consumer 수가 증가할수록 처리량은 늘어난다. 


Consumer Group 수에 따른 성능 비교

2 broker 기준 (Test 토픽 2파티션)

Consumer Group 수에 따른 결론

컨슈머 그룹이 늘어나도 성능 저하가 없다.




결론

브로커 1노드 기준으로 ssd hdd보다 처리량이 2 높으나 hdd Raid 묶으면 ssd 비슷한 성능이 가능하다. (비용 측면 검토 필요)
Producer와 Consumer를 같이 사용하기 때문에 처리량에 따른 하드웨어 스펙을 검토되어야  한다. 

프로덕션 환경 권장사양






Posted by 사용자 피랑이

댓글을 달아 주세요

  1. AndersonChoi 2019.08.30 16:44 신고  댓글주소  수정/삭제  댓글쓰기

    직접 node를 띄워서 테스트하시느라고 비용(시간, 돈)이 많이 들었을거 같아요.
    소중한 정보 공유주셔서 감사합니다.

  2. Lucsa Lee 2020.05.26 11:41  댓글주소  수정/삭제  댓글쓰기

    고생 많이 하셨습니다. Kafka 공부하는데 큰 도움이 되었습니다. 감사합니다.

  3. 2021.01.17 15:27  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

Docker : 기초 편

Docker 2019. 1. 16. 19:42

[Docker : 기초 편]

[Docker : 설치 편]

[Docker : 컨테이너 편]



Docker란?


Docker(이하 도커)는 운영체제 급(Operation System Level)의 가상화를 수행하는 컴퓨터 프로그램이다.

여기서 운영체제 급 가상화 컨테이너 화(Containerization) 라고도 한다.



도커는 어플리케이션을 가상머신기반 게스트OS를 통해 구동되는 방식에서 도커엔진 기반의 컨테이너에서 구동 되도록

설계함으로써 게스트OS 없이 어플리케이션을 구동 할 수 있게 되었다. 

도커를 설명하기에 앞서 먼저 가상화 개념에 대한 설명부터 하고자 한다.





가상화(Virtualization)란?



가상화는 컴퓨터에서 컴퓨터 리소스의 추상화를 일컫는 단어로, 

쉽게 설명하면 컴퓨터 속에 가상의 컴퓨터를 만들어내는 기술이다.





가상화는 왜 사용하는걸까?


세 대의 서버가 있다고 가정 해보자 각각의 서버는 메일, 인증, 그룹웨어 서비스가 가동되고 있다.

자원은 각 서버별로 25%, 30%, 20%씩 사용하고 있고 서버별 자원 활용률이 90%가 최대치라고 가정 한다면 현재 65%, 60%, 70%의 자원이 놀고 있는 상태가 된다.


일단 구조는 아래와 같다. 각 서버에 OS가 설치 되어 있고 그 위에서 서비스가 가동중이다.


그렇다면 어떻게 자원낭비를 없앨 수 있을까?




"그냥 3개의 서비스를 하나의 OS로 몰아주면 될 것 같은데?"



좋은 생각이다. 그런데 여기서 미처 생각하지 못한 부분이 있다. 다음 예를 보자


메일 서비스에 신규 기능이 추가 되었다. 이 기능을 사용하려면 OS버전의 업데이트가 필요한 상황이다.

인증 서비스와 그룹웨어는 OS업데이트가 불필요한 상황이고 오히려 업데이트를 하면 OS버전 호환 문제로 서비스에 지장을 주게 된다.

결국 OS업데이트로 인하여 3개 서비스의 호환성을 모두 확인하고 서비스를 수정하는 작업이 발생하게 되었다.


다른 예로 A부서에서만 쓰던 서버를 B부서에서도 쓰겠다고 한다. 마침 A부서와 B부서는 별도의 인증 서비스를 운영하고 있었다. 

하필이면 서비스명이 같고 설정도 많이 겹친다. 어떤 일이 벌어질까?


"포트 겹치는건 기본이고 바꿔야 할 설정들이 너무 많습니다."



최악의 경우에는 서비스의 설정들을 모두 바꿔야 하는 일이 생겨버린다.

혹은 Host OS가 Windows Server 였는데 리눅스 서버가 필요한 상황이라면? 서버 한대로는 도저히 답이 안나온다.

그럼 각 OS와 서비스가 독립적일수는 없을까?


이러한 경우 가상화 기술을 사용하여 해결 할 수 있다.

한 대의 서버에서 하이퍼바이저를 통한 물리자원의 논리적 분할로 여러개의 Virtual Machine에서 각각의 Guest OS를 생성 할 수 있다.

생성된 Guest OS는 독립적으로 운용이 가능하다. 3개의 각 Virtual Machine에서 Guest OS를 3개 생성한다면 서버 한 대로 세 대의 서버를 가진것이 된다. 3천원어치같은 천원어치 떢볶이를 떠올리면 된다.



이제 서비스의 간섭과 충돌에서 자유로워졌다.

그러나 다른 문제가 또 있으니...




왜 Docker를 사용해야 하는가?


앞서 설명한 Virtual Machine 기반에서 Application을 구동 하려면 Guest OS가 필요하다.

기본적으로 OS에만 소모되는 자원이 상당하고 가상 OS를 통한 Application의 실행은 무겁고 느려서 실제 운영환경에 효율이 상당히 떨어졌다.


그 후 도커가 출시 되었다.

도커는 컨테이너를 기반으로한 가상화 플랫폼으로 컨테이너는 프로세스를 격리 시키는 기술이다.


Virtual Machine 기반의 Guest OS에서 Apache와 Mysql이 실행중이라고 할 때

도커 엔진이라면 하나의 컨테이너에 Apache 프로세스가, 또 다른 컨테이너에는 Mysql 프로세스가 독립적으로 실행 된다.

즉 Guest OS의 의존 없이 격리된 하나의 프로세스를 만들 수 있게 되었는데, 이는 성능향상뿐만 아니라 엄청난 비용절감 효과를 가져올 수 있다.




Virtual Machine 대비 도커 컨테이너의 장점 요약


1. 가볍다

Virtual Machine 기반에서 Application을 구동하기 위해서는 반드시 Guest OS가 존재 해야하므로 그만큼 이미지의 사이즈도 커진다. 반면 도커 컨테이너는 Host OS에서 도커엔진을통해 구동되고 필요한 만큼의 자원만 사용하므로 Virtual Machine 대비 매우 가볍다.



2. 빠르다

Virtual Machine 기반에서는 무조건 Guest OS를 경유하여 Application을 실행 해야만 했다. 때문에 처음부터 하나의 Application을 실행하기 위해서는 Guest OS부터 구동해야 하는데 부팅시간은 최소 분 단위이다. 도커 컨테이너는 Guest OS를 경유하지 않으므로 몇 초만에 실행된다.



3. 배포가 용이하다

Virtual Machine에서 이미지 배포를 위해서는 Guest OS가 필요하므로 이를 포함하여 이미지로 만든 후 배포 해야한다. OS 기본설치만 해도 기가단위의 용량이 넘어가므로 이미지 배포는 용량이 적은 도커 컨테이너와 비교하면 매우 비효율적이다. 도커 컨테이너는 필요한 Application의 용량만큼을 이미지로 만들어 배포하므로 효율적이다.





Docker : 기초 편

끝.

'Docker' 카테고리의 다른 글

Docker : Dockerfile 실습 편  (0) 2019.03.22
Docker : Dockerfile 편  (0) 2019.03.07
Docker : 이미지 편  (0) 2019.02.22
Docker : 컨테이너 편  (1) 2019.02.15
Docker : 설치 편  (0) 2019.01.31
Docker : 기초 편  (2) 2019.01.16
Posted by DevStream

댓글을 달아 주세요

  1. MJ 2020.06.16 12:08  댓글주소  수정/삭제  댓글쓰기

    VM기반의 Guest OS에서 Application을 실행시키는 게 그 실행하고자 하는 어플리케이션이 Guest OS에 의존적이기 때문아닌가요? 만약 Windows OS만 지원하는 Application인 경우에는 Docker 엔진에서는 가동할 수 있나요? 만약 그렇다면 어떻게 가동할 수 있나요??

    • DevStream 2020.06.18 15:12 신고  댓글주소  수정/삭제

      "VM기반의 Guest OS에서 Application을 실행시키는 게 그 실행하고자 하는 어플리케이션이 Guest OS에 의존적이기 때문아닌가요?"
      -> 맞습니다. 실행하고자 하는 어플리케이션은 OS에 의존적입니다. 예를들어 윈도우즈용 exe파일을 리눅스에서 그냥 실행하면 실행이 되지 않습니다. 해당 어플리케이션이 Windows OS에 종속적이기 때문입니다. (물론 리눅스에서 exe프로그램을 아예 실행할 수 없는건 아닙니다만 wine이라는 별도의 패키지를 설치해야 하는 등 우회에 가까우므로 이것은 논외로 하겠습니다.)

      "만약 Windows OS만 지원하는 Application인 경우에는 Docker 엔진에서는 가동할 수 있나요? 만약 그렇다면 어떻게 가동할 수 있나요??"
      -> 가능합니다. Windows OS에서 도커엔진을 통해 Windows 컨테이너를 생성할 수 있습니다. Windows OS전용 어플리케이션이므로 Windows OS에 설치된 도커엔진을 기반으로 구동됩니다.

      아래 링크는 1809버전의 도커엔진으로 간단한 웹 서버를 구현하는 예제입니다.
      https://stefanscherer.github.io/how-to-run-lightweight-windows-containers-on-windows-10/

      덧붙여서..
      각 어플리케이션들은 각각의 OS에 종속적입니다. 예를들어 nginx 웹서버 어플리케이션은 윈도우즈용, 리눅스용 두 가지 버전을 지원합니다. 윈도우즈에서 리눅스용 nginx는 일반적으로는 실행할 수 없습니다. 이것을 가능하게 하려면 네이티브 리눅스환경을 구축하거나 윈도우즈OS에서 VM을 통한 리눅스OS 환경을 만들거나 윈도우10에서 지원하는 WSL을 이용해야 합니다.