System Compleat.

고가용 서비스 - Spring Cloud - #5 Deploy your applications to the cloud / Cloud Foundry

Techs


(younjin.jeong@gmail.com, 정윤진) 

지금까지 이런저런 스프링 부트/스프링 클라우드에 대한 내용을 살펴보았는데, 사실 더 진행을 위해서는 또 다른 역할을 하는 마이크로 서비스를 만들어 내야 한다. 그런데 사실 로컬 랩탑에서 이런저런 마이크로 서비스들을 서로 다른 포트로 localhost 에서 돌리는것은 꽤나 귀찮은 일이 아닐수 없다. 그리고 아마 스프링 부트를 살펴보시는 분들이 하고계시는 고민중의 하나가 아마도 "어? WAS를 따로 안써도 된다고? 그럼 서비스는 어떻게 돌려?" 일 것이다. 물론 java -jar 의 방법이 아름답지만, 수십 수백기가의 메모리가 달려있는 서버에서 딸랑 저렇게 수행하는 것은 뭔가 맞지 않는 느낌적인 느낌이다. 그래서 docker 를 사용해서 올리거나 하는 방법을 사용할 수 있지만 뭐 요새 docker 는 하도 사방에서 이야기가 많으니까 나는 그걸 하지 않는 것으로 하고... 


이런 도구를 왜 굳이 설치해서 사용해야 하느냐? 클라우드 어쩌고 이런 말은 일단 빼고 간략히 설명하면, 

- 개발된 애플리케이션의 배포를 빠르게 수행하고 싶다. 

- 각각의 애플리케이션을 80/443 포트에서 구동할 필요가 있다. 

- 마이크로 서비스 구현 및 개발을 위해 필요한 애플리케이션 여러개를 동시에 동작해야 할 필요가 있다. 

- Redis, RabbitMQ, MySQL 의 리소스를 사용한 애플리케이션 개발을 해야 할 필요가 있다. (물론 다른 도구들도 리소스가 있다면 연결 가능하지만, 위의 세개 서비스를 즉각 할당 받아 사용할 수 있으므로.) 

- 로컬에서 docker 컨테이너를 여러개 돌렸을때 발생하는 의존성들에서 자유롭고 싶다. 


개발, 테스트 및 학습을 위해 오늘은 Cloud Foundry 를 소개한다. 회사에서 서버 레벨로 구동하지 않는 경우를 제외하고 개발자를 위한 환경을 소개하면 두가지 방법이 있는데, 하나는 PCFDEV 라고 불리는 로컬용 개발 버전을 사용하는 것과 다른 하나는 Pivotal Web Services 라고 불리는 환경을 60일 정도 무료로 제공받아 사용하는 방법이 있다. 로컬 버전을 설치하거나 PWS를 사용하거나 클라이언트 도구가 올라간 이후에 사용 방법은 동일하기 때문에 별 문제될 것은 없다. 다만 PWS를 사용하는 경우 백엔드 서비스의 선택폭이 다양하기 때문에 편리할 수 있다. 


Pivotal Web Services - 신용카드 등록 따위 없이 후리티어를 경험합시다! 

먼저 PWS 를 사용하는 방법은 간단하다. https://run.pivotal.io 의 도메인으로 접근한 뒤, 페이지의 안내에 따라 sign-up for free 버튼을 누르고 로그인 화면이 나오면 아래 "create account" 를 클릭해서 필요한 내용을 기입하면 된다. 

패스워드 복잡성 체크를 예쁘게 해준다. 그러면 Pivotal 로 부터 Verification 메일이 하나 온다. 메일은 요렇게 생겼다. 

이메일 안의 Verify your email address 를 클릭하면 아래와 같은 Free trial 등록 페이지로 넘어간다. 사용을 위해, SMS 를 선택하고 Korea, Republic of 를 선택한다. 그리고 제일 아래에는 모바일 번호를 넣어주면 된다. 그냥 한국 전화 번호 010-xxxx-xxxx 를 넣어도 정상적으로 문자 메세지가 수신 되는데, 만약 잘 안된다면 국가 번호를 더해서 넣어 보아도 된다. 

그러면 페이지가 넘어가면서 문자 메세지를 전화번호로 보냈으니 살펴서 코드를 입력하라 한다. 

개인정보 보호를 위해 선글라스를 씌웠더니 이미지에 검은색 배경이 생긴다능...  

화면이 넘어가면서 Org 라는걸 생성하라고 한다. 얘는 조직 이름인데, 블로그를 보고 따라 하시는 분들 께서는 거의 개인 목적의 사용일 테므로 원하는 이름을 주면 된다. 기본으로 주어지는 이름을 사용해도 되지만 아마 전체 계정에서 유일한 이름을 사용해야 할 필요가 있을지도 모르겠다. 아무튼 기억할건 이 이름이 너무 길면 나중에 타이핑이 좀 힘들 수 있으므로 간략하고도 유니크한 나만의 조직 이름을 선택하도록 하자. 

아울러 페이지의 오른쪽에 보면 어떤 서비스를 얼만큼 무료로 사용할 수 있는지 나온다. 프리 트라이얼 기간이 끝나면 청구되는거 아냐! 하고 겁내지 말자. 일단 신용카드 정보 기입과 같은 단계는 없다. 무료 사용 금액을 넘어가는 리소스는 쿼터로 제한되어 어차피 구동되지 않는다. 하지만 1년이 지나면 동작하던 서비스들이 중단될 수 있으므로 주의할 필요는 있겠다. 아울러 이 PWS 는 현재 미국 동부의 아마존 웹 서비스 위에서 기동되고 있으므로 속도가 찌끔 느리더라도 아 멀어서 그렇겠거니 하시면 된다. 

자, 이제 PWS 사용을 위한 준비가 모두 끝났다. 로컬 버전 설치를 원하지 않는 경우라면 다음의 pcfdev 부분을 건너 뛰고 보시면 되겠다.  


pcfdev - 누가 뭐래도 나는 로컬이 짱이야! / 우리 회사는 방화벽이 빡세거든! / 내가 만든 애플리케이션은 나만 봐야지! 

다음의 링크는 각각 pcfdev 를 로컬에 다운로드 받아 구동에 대한 설명이다. 그다지 어려울 것은 없고, 윈도우든 맥이던 Virtualbox 를 준비한 이후 pcfdev.io 또는 network.pivotal.io 에서 개발 버전을 다운로드 받을 수 있겠다. 물론 코드가 궁금하신 분은 오픈소스이므로 아래의 깃헙 링크를 참조하실 수도 있겠다. https://github.com/pivotal-cf/pcfdev 


윈도우용 설치 : https://docs.pivotal.io/pcf-dev/install-windows.html

OSX 용 설치 : https://docs.pivotal.io/pcf-dev/install-osx.html


pcfdev 를 사용하여 랩탑이나 데스크탑의 개발 환경에서 운용 하는 방법은 의외로 간단하다. cf dev start / cf dev stop 의 커맨드로 필요한 환경을 들었다 놓았다 할 수 있다. 시스템에 기본적으로 20기가 바이트 이상의 디스크 여유 공간과 8기가 바이트의 메모리가 탑재되어 있어야 하며, 사실 이클립스나 IntelliJ 같은 도구를 같이 틀어놓고 작업하려면 16기가바이트의 메모리를 가진 머신에서 사용하는 것을 권고 한다.  

위의 링크에 나온대로 살짝 따라하다 보면 어느새 내 랩탑에도 클라우드 파운더리가 뙇! 

Downloading VM...
Progress: |====================>| 100%
VM downloaded
Importing VM...
Starting VM...
Provisioning VM...
Waiting for services to start...
40 out of 40 running
 _______  _______  _______    ______   _______  __   __
|       ||       ||       |  |      | |       ||  | |  |
|    _  ||       ||    ___|  |  _    ||    ___||  |_|  |
|   |_| ||       ||   |___   | | |   ||   |___ |       |
|    ___||      _||    ___|  | |_|   ||    ___||       |
|   |    |     |_ |   |      |       ||   |___  |     |
|___|    |_______||___|      |______| |_______|  |___|
is now running.
To begin using PCF Dev, please run:
    cf login -a https://api.local.pcfdev.io --skip-ssl-validation
Admin user => Email: admin / Password: admin
Regular user => Email: user / Password: pass

메모리나 코어를 조금 더 할당하고 싶다면 -m 스위치와 -c 스위치를 사용하여 환경을 구동할 수 있다. 

$ cf dev start -m 8192 -c 4

환경이 필요 없다면 아래의 커맨드로 간단히 모든 환경을 종료 할 수 있다. 

cf dev stop 

PWS는 인터넷에 공개된 환경이고, 제한된 쿼터이긴 하지만 소규모로 프로덕션으로 사용할 수도 있기는 하다. 다만 실제 서비스에 유입되는 트래픽 규모가 커진다면 그때는 쿼터를 해제하거나 별도의 방법을 사용할 필요가 있다. 반대로 PCFDEV는 "개발"을 위한 환경이며 절대로 프로덕션용 서버에 배포해서 사용하는 일이 없도록 한다. 

두 도구의 차이는 아래의 이미지에서 살펴볼 수 있다. 

https://pivotal.io/pcf-dev


클라우드 파운더리는 기본적으로 꽤 많은 인스턴스를 만들어 낸다. 로컬이던 프로덕션용이건 간에 암튼 많다. 이게 왜 많냐면, 다음과 같은 것들을 개발자가 신경쓰지 않게 해 주기 때문이라고 생각하면 된다. 

- 동적 로드밸런싱, 도메인 라우팅 

- 헬스 모니터링

- 컨테이너 이미징 

- 로그 어그리게이션 

- 컨테이너 오케스트레이션

- 컨테이너 기동 

- MySQL, RabbitMQ, Redis 인스턴스 

- API 인증 

- 앞에서 소개한 Config server, Circuit breaker, Registry (유레카) 의 3개가 서비스로 이미 뙇! 

- 업로드된 빌드/아티팩트 저장, 보관 

- 기타 등등 오퍼레이션 잡무 


준비 됬다면? 고고고 

위의 도구들 중 하나가 준비 되었다면 cf 라는 클라이언트를 통해 애플리케이션의 배포가 가능하다. PWS를 사용하는 경우라면, 로그인 후 나오는 웹 인터페이스에서 왼쪽을 보면 "Tools" 탭이 있다. 클릭하면 각 운영체제에 맞는 클라우드 파운드리의 클라이언트 도구를 다운로드 받을 수 있다. cf 클라이언트가 준비 되었다면, 다음의 과정을 수행한다. 

PWS의 경우 : 

$ cf login -a https://api.run.pivotal.io 

pcfdev 의 경우 : 

$ cf login -a https://api.local.pcfdev.io --skip-ssl-validation
Email>  admin

Password>
인증 중...
확인

조직 선택(또는 Enter를 눌러 건너뜀):
1. pcfdev-org
2. system

Org> 1
대상 지정된 조직 pcfdev-org

대상 지정된 영역 pcfdev-space

로그인이 완료되면, 이제 다양한 cf 클라이언트를 사용할 수 있다. 먼저 cf apps 를 때려 보면 현재 조직의 "스페이스" 라고 불리는 환경에 동작하는 모든 애플리케이션 리스트를 보여준다. 아마 처음 PWS를 사용하거나 pcfdev 를 사용하면 아무런 애플리케이션이 보이지 않을 것이다. 

$ cf apps
yjeong@pivotal.io(으)로 yjeong-org 조직/development 영역의 앱 가져오는 중...
확인

앱을 찾을 수 없음


최근의 pcfdev 는 아래와 같은 웹 콘솔까지 제공한다.  https://console.local.pcfdev.io 로 접근하면 된다. 임의로 만든 SSL 인증서를 사용하므로 접근시 등장하는 경고는 무시해 주면 된다. 


자, 그럼 이제 이전 시리즈에 만들어 두었던 애플리케이션들을 구동해 보자. 

- Config-server

- Discovery-service

- Zipkin-service 

- helloworld-service 

- helloworld-client 

의 순서대로 푸시한다. 먼저 빌드하고, 

$ ./mvnw clean package

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building config-server 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
..
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.762 s
[INFO] Finished at: 2016-10-21T12:37:50+09:00
[INFO] Final Memory: 35M/278M
[INFO] ------------------------------------------------------------------------


push, 즉 배포를 수행한다. 

$ cf push config-server -p target/config-server-0.0.1-SNAPSHOT.jar

admin(으)로 pcfdev-org 조직/pcfdev-space 영역에 config-server 앱 작성 중...
확인

config-server.local.pcfdev.io 라우트 작성 중...
확인

config-server에 config-server.local.pcfdev.io 바인드 중...
확인

config-server 업로드 중...
업로드 중인 앱 파일 원본 위치: /var/folders/j0/vxfr0q8d2mx58xt27jx2dsd80000gn/T/unzipped-app841413472
38.1M, 185 파일 업로드
Done uploading
확인


admin(으)로 pcfdev-org 조직/pcfdev-space 영역에서 config-server 앱 시작 중...
Downloading dotnet_core_buildpack_beta...
Downloading python_buildpack...
Downloading binary_buildpack...
Downloading php_buildpack...
Downloading staticfile_buildpack...
Downloaded binary_buildpack (9.1K)
Downloading go_buildpack...
Downloaded staticfile_buildpack
Downloading java_buildpack...
Downloaded java_buildpack (246M)
Downloading ruby_buildpack...
Downloaded go_buildpack (320.8M)
Downloading nodejs_buildpack...
Downloaded dotnet_core_buildpack_beta (99.4M)
Downloaded python_buildpack (255.2M)
Downloaded nodejs_buildpack (96.7M)
Downloaded ruby_buildpack (261.5M)
Downloaded php_buildpack (274.9M)
Creating container
Successfully created container
Downloading app package...
Downloaded app package (33.9M)
Staging...
-----> Java Buildpack Version: v3.8.1 (offline) | https://github.com/cloudfoundry/java-buildpack.git#29c79f2
-----> Downloading Open Jdk JRE 1.8.0_91-unlimited-crypto from https://java-buildpack.cloudfoundry.org/openjdk/trusty/x86_64/openjdk-1.8.0_91-unlimited-crypto.tar.gz (found in cache)
Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (0.8s)
-----> Downloading Open JDK Like Memory Calculator 2.0.2_RELEASE from https://java-buildpack.cloudfoundry.org/memory-calculator/trusty/x86_64/memory-calculator-2.0.2_RELEASE.tar.gz (found in cache)
Memory Settings: -Xms104169K -XX:MetaspaceSize=64M -Xmx104169K -XX:MaxMetaspaceSize=64M -Xss228K
-----> Downloading Spring Auto Reconfiguration 1.10.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-1.10.0_RELEASE.jar (found in cache)
Exit status 0
Staging complete
Uploading droplet, build artifacts cache...
Uploading build artifacts cache...
Uploading droplet...
Uploaded build artifacts cache (108B)
Uploaded droplet (79.4M)
Uploading complete
Destroying container
Successfully destroyed container

0 / 1 인스턴스 실행 중, 1 시작 중
1 / 1 인스턴스 실행 중

앱 시작됨


확인

`CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-2.0.2_RELEASE -memorySizes=metaspace:64m..,stack:228k.. -memoryWeights=heap:65,metaspace:10,native:15,stack:10 -memoryInitials=heap:100%,metaspace:100% -stackThreads=300 -totMemory=$MEMORY_LIMIT) && JAVA_OPTS="-Djava.io.tmpdir=$TMPDIR -XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh $CALCULATED_MEMORY" && SERVER_PORT=$PORT eval exec $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp $PWD/. org.springframework.boot.loader.JarLauncher` 명령을 사용하여 config-server 앱이 시작되었습니다.

admin(으)로 pcfdev-org 조직/pcfdev-space 영역에서 config-server 앱의 상태 표시 중...
확인

요청된 상태: started
인스턴스: 1/1
사용법: 256M x 1 인스턴스
URL: config-server.local.pcfdev.io
마지막으로 업로드함: Fri Oct 21 03:38:16 UTC 2016
스택: unknown
빌드팩: java-buildpack=v3.8.1-offline-https://github.com/cloudfoundry/java-buildpack.git#29c79f2 java-main open-jdk-like-jre=1.8.0_91-unlimited-crypto open-jdk-like-memory-calculator=2.0.2_RELEASE spring-auto-reconfiguration=1.10.0_RELEASE

상태 이후 CPU 메모리 디스크 세부사항
#0 실행 중 2016-10-21 12:39:07 PM 0.0% 185.2M / 256M 160.7M / 512M

배포후 정보를 보면 URL 부분에 배포된 애플리케이션이 어느 주소로 동작하고 있는지 나온다. config-server 를 배포해 보았으므로 정상적으로 동작하는지 확인해 보자. 

$ curl http://config-server.local.pcfdev.io/account-service/cloud | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 936 100 936 0 0 499 0 0:00:01 0:00:01 --:--:-- 498
{
"name": "account-service",
"profiles": [
"cloud"
],
"label": "master",
"version": "dc82fb551c53e86af22e064eedfb35678e98917e",
"propertySources": [
{
"name": "https://github.com/younjinjeong/demo-config/application.properties",
"source": {
"eureka.instance.hostname": "${vcap.application.uris[0]:localhost}",
"logging.level.com.netflix.discovery": "OFF",
"eureka.client.registryFetchIntervalSeconds": "5",
"spring.sleuth.sampler.percentage": "1.0",
"logging.level.com.netflix.eureka": "OFF",
"server.port": "${PORT:0}",
"endpoints.shutdown.enabled": "true",
"eureka.instance.leaseRenewalIntervalInSeconds": "3",
"eureka.instance.prefer-ip-address": "true",
"eureka.instance.metadataMap.instanceId": "${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}}",
"info.id": "${spring.application.name}:${server.port}",
"eureka.client.region": "default",
"spring.jpa.generate-ddl": "true",
"spring.sleuth.log.json.enabled": "true"
}
}
]
}


pcfdev 또는 PWS 에 환경이 준비 되었다면, 이제 다음 포스팅에서 본격적으로 애플리케이션을 구동하고 데이터 소스와 연동하는 방법을 살펴 보겠다. 일단 어디든 올릴데가 생겨야 서킷 브레이커든 다른 스프링 클라우드 관련 리소스를 올려서 테스트 할 수 있을 듯. 오늘은 힘드니까 여기까지. 


(younjin.jeong@gmail.com, 정윤진) 





고가용 서비스 - Spring Cloud - #3 Smart microproxy - Zuul

Techs


(younjin.jeong@gmail.com, 정윤진) 

로드 밸런서라는 것을 처음 접했던것은 리눅스의 LVS 였다. 1990년대 말엽 쯤이었던것 같은데 트래픽을 분산 처리할 수 있다는 개념에 매우 놀라워 했던 기억이다. 당시 리눅스 배포판에는 모두 How to 문서가 함께 배포 되었었는데 여기에 소개된 LVS 를 구현 하려면 깡통 머신이라도 몇대는 있어야 했기 때문에 침만 꿀떡 삼키곤 했다. 

LVS - HA  http://www.linuxvirtualserver.org/  (이 사이트가 아직 살아있다니)

후에 국내 대규모 호스팅 업체에서 연구원으로 이런 저런 서비스를 개발하면서 당시 이슈가 되던 DDoS 처리와 함께 네트워크 기반의 밸런서가 아닌 리눅스 박스 기반의 밸런서를 회사에서 고려하면서 직접 구현할 기회가 생겼더랬다. 지금은 매우매우 유명해져서 인천 국제공항 짐 찾는데서 광고도 하고 있는 모 인터넷 쇼핑몰이 그때 장사가 폭발하기 시작하면서 서버의 부하 분산 처리를 해야 했는데, 기존의 서버를 웹 애플리케이션 서버와 웹 서버로 나누고 Memcached 와 같은 도구의 사용과 PHP 의 프로파일링을 opcode 레벨로 수행하기도 하고 뭐 여러가지를 붙이면서 여기에 LVS도 들였던 기억이다. 왜냐면 지금 아마존도 그렇지만 호스팅은 원가 절감에 사업 생명이 달려있기 때문에... 

어쨌든 로드 밸런싱이라는 것은 외부에서 들어오는 웹 또는 트래픽을 내부의 여러대의 서버로 분산해서 처리하는 것을 말한다. 지금은 믿기 힘들겠지만 예전에는 한대의 서버에서 웹 서버, 데이터베이스 이런것들을 다 구동시키던 시절도 있었... 그리고 로드 밸런서는 이 부하를 분산해 주는 역할을 하는 서버나 네트워크 장치 또는 소프트웨어 또는 어플라이언스를 말한다. 이런 기능이 제공하는 성능 향상은 그야말로 확장이 거의 불가능한 관계형 데이터베이스가 퍼질때까지 웹 서버를 늘릴 수 있는 장점이 있다. 게다가 로드 밸런서 뒷쪽에 있는 서버에 장애가 발생하거나 업데이트를 하는 경우에도 트래픽의 핸들링이 가능하기 때문에 서비스의 가용성이 더 높아지는 이유도 있다. 따라서 서비스에 유입되는 트래픽이 증가하는 특정 시점에는 반드시 로드 밸런서의 도입을 고려해야 하는 시점이 있었다. 물론 루프백 인터페이스의 수정과 같은 대규모 작업과 함께. 

밸런서에 대해 조금 더 이야기 해 보자면, 이런 리눅스 박스 기반의 밸런서를 구성하는 것은 뭐 약간의 기술이 필요하기 때문에 이런 구성의 편의를 위해서 리눅스 박스를 벤더별로 커스터마이징 해서 아예 네트워크 장치 처럼 내어 놓는 '어플라이언스형' 밸런서들이 유행을 타기 시작했다. 물론 편의 뿐만 아니라 다양한 네트웍적인 기능, 그리고 편리한 웹 기반의 인터페이스, 그리고 일부 암호화 같은 기능들의 경우에는 순수 소프트웨어를 사용하는 대신 별도의 ASIC을 사용하기 때문에 더 높은 성능을 보이는 것들도 있었다. 처음에는 노텔이, L4 로 대표되는 스위치로 흥하다가 이후에는 F5 와 같은 벤더에서 강력한 L7 기능과 함께 컨텐츠 캐싱과 같은 복합적인 역할을 수행하는 제품을 내어 놓기도 했고, Citrix 와 같은 벤더에서는 WAN 구간의 데이터 전송에 더 적은 트래픽을 사용하는 압축 기술 등을 적용한 제품을 내어 놓기도 한 나름대로 흥망성쇠가 있는 레이어였다. 

여담이긴 하지만 이런 로드 밸런서를 본격적으로 사용하기 전에는 RRDNS 라고 해서 동일한 네임서버의 레코드에 여러개의 서버 주소를 넣어서 요청하는 클라이언트 별로 순차적으로 응답을 주는 방식을 사용하기도 했었다. 이 DNS 작업을 서버의 IP 주소 레벨로 처리 했을때를 상상해 보면 어떨까 생각해 보길 바란다. 그래서 사람들은 서버들은 로드 밸런서에 연결하고 로드 밸런서에도 부하가 생기기 시작하면 여러개의 로드 밸런서를 마련하여 이 로드 밸런서의 주소를 DNS 에 등록하는 방식을 사용하게 된다. 그리고 여기에 발전하여 DNS 가 점점 똑똑해 지면서 클라이언트의 IP가 어느 지역에 위치한지를 GeoIP 와 같은 데이터베이스를 통해 알아내서 그 지역에 가까운 로드 밸런서의 주소를 할당해 주는 형태로 발전하게 된다. 이게 RRDNS 부터 GSLB 라고 불리는 방식으로의 발전이다. 


아무튼 이런 전통적인 방식의 로드 밸런서들은 끊임없이 발전했는데, 그중 한 부분이 바로 고가용성 부분이다. 약 7년전 까지만 하더라도 로드 밸런서를 Active-active 로 (즉 두대 다 동시에 사용가능하게) 하는 구성은 돈도 비싸고 네트웍적으로도 골치 아픈 것이었다. 두대의 어플라이언스 기반 로드 밸런서를 고가용성으로 구성하려면 거의 대부분 가능한 옵션은 Active-Standby(두대중 한대만 가용) 였고, 이 구성 마저도 로드밸런서간 세션 공유를 위한 네트웍 회선 이중화 구성, 로드 밸런서가 연결되는 라우팅 구간과의 Port trunking 을 연계한 HSRP 또는 VRRP 구성, 그리고 내부의 네트워크 장비와의 고가용성 연결 등 이게 그렇게 단순한 이야기가 아니었던 거다. 더 중요한 것은, 서비스를 운영하는 관점에서 보면 네트워크는 네트워크 장치끼리 따로 움직이는 것이 아니다. 이는 각 역할을 하는 서버와 연결되며, 각 서버는 또 기본적으로 Bonding / Teaming 이라고 불리는 이중화 기술을 사용하고 만약 윈도우를 사용한다면 클러스터링 여부에 따라 AD 구성이 필요하게 된다. 그리고 만약 데이터베이스 클러스터를 SAN 기반으로 구성했다면 역시 데이터베이스의 tablespace 위치 설정과 SAN의 Zoning 작업, HBA 설정등 모든게 거대한 하나의 세트가 된다. 이런 클러스터링의 정상 동작은 상단의 밸런서 구간, 그리고 서버와 서버의 연결 구간이 일목 요연하게 동작해야 비로소 아름답게 (라고 쓰고 비싼 돈 들여서 정상적으로 동작하는거 구경이라고 읽는..) 동작한다. 

F5 Networks LTM - 한때는 매우 아름다운 고성능의 어플라이언스  전원을 넣으면 오른쪽 다마에 불이 켜져요 

암튼 사설이 너무 길었는데, 로드 밸런서가 active-active 의 고가용성으로 구동되기 힘들었던 이유중 가장 큰 것은 바로 '세션 클러스터링' 이라는 기능때문이었다. 보통 Sticky bit 또는 persistence 라고 불리는 밸런서의 기능은 현재 어느 클라이언트가 내부의 어느 서버와 연결되었는지에 대한 연결 정보를 기억한다. 이건 개발자들에게 웹 애플리케이션에서 세션을 서버 로컬에 저장해도 되는 편리함을 제공했다. 그래서 역설적으로 이 기능이 없는 밸런서를 사용하면 웹 서비스가 정상동작 하지 않기도 하는 경우가 있었다. 

그래도 역시 이런 고가의 어플라이언스는 별로야 라고 생각했던 사람들은 리버스 프락시라는 도구에 주목한다. 세션 클러스터링 따위 REST로! 라고 사람들이 생각하기 시작하면서, 그리고 클라우드가 대두되면서 리버스 프락시는 널리 사용되기 시작한다. 이 블로그에 NginX 를 처음 소개했던게 2009년이란다. 세월 참 빠르다. 아무튼 Nginx, HAProxy, Varnish 와 같은 리버스 프락시들은 단순히 로드 밸런싱 뿐만 아니라 HTTP 헤더의 조작, uri 기반으로 내부의 서버를 선택해서 포워딩 할 수 있는 등의 참으로 아름다운 기능들을 제공하기 시작한다. 특히 나는 Nginx 를 매우 사랑했는데, 모듈을 통한 손쉬운 기능확장, 이를 테면 memcached 를 붙여 시원한 캐시를 할당한다던가 SSL 엔드포인트로 사용한다던가 CPU affinity 설정과 같은 매니악한 기능들, 그리고 uri 라우팅을 통한 인증서버, 파일(이미지) 서버, 그리고 웹 애플리케이션 서버를 내맘대로 밸런싱하는 재미가 있었기 때문이다. 

어쨌든, 세션 클러스터링 따위가 별게 아닌게 되기 시작하면서 밸런서는 소프트웨어로 손쉽게 확장할 수 있는 도구가 되었고 이런 기능성은 클라우드 위에서 매우 매력적인 도구가 되었다. 그런데, 클라우드 서비스는 대부분 밸런서를 기본으로 제공하고 (처음부터 기본은 아니었지만) 있다. 아마존의 ELB(Elastic Load Balancer)만 해도 처음에는 그냥 밸런싱만 하는 깡통이더니, sticky 지원을 시작해서 connection drain 등 점점 예전 상용 밸런서와 같은 기능을 제공하고 있다. 


옛날 이야기는 이쯤 하기로 하고, 이런 부하를 분산하는 기능을 했던 밸런서는 ELB 로 충분한데 클라우드 기반의 서비스가 발전하면서 더 많은, 즉 더 똘똘한 "무엇"이 필요하게 된다. "무엇"을 대충 정리하면 아래와 같다. 

- 단순이 네트워크적 라우팅 또는 L7 '지원' 수준의 분배가 아닌, 실제 애플리케이션 레벨에서의 백엔드 애플리케이션 연결 

- 동적인 라우팅, 즉 설정따위 변경 없이 리소스의 생성과 삭제에 따른 라우팅 즉각 반영 

- 모니터링 

- 빠른 복구, 그리고 보안성 

- 추가 기능, 예를 들면 아마존 웹 서비스에 위치한 다수의 오토 스케일링 그룹으로의 리퀘스트 라우팅 

예를 들면 샤드로 구성된 데이터베이스들에 요청을 분배해야 하는 경우를 생각해 볼 수 있다. 이러한 요구사항을 서비스를 지속적으로 개선함에 따라 발견했던 넷플릭스는, 처음에는 외부의 상용 서비스를 사용하다가 결국 Zuul 이라는 새로운 도구를 만들어 내었다.

Zuul, the Gatekeeper from Ghostbusters movie - http://villains.wikia.com/wiki/Zuul 


이름이 의미하는 바와 같이 이는 서비스의 대문을 지키는 수장의 역할을 한다. 이 Zuul 이 제공하는 기능을 정리해 보면 다음과 같다. 

- 인증 및 보안 : 각 요청이 갖추어야 할 내용을 충족하지 못한 경우 해당 요청을 거부한다. 

- 모니터링 : 모든 트래픽이 지나기 때문에 의미있는 데이터와 지표를 수집할 수 있다. 

- 동적 라우팅 : 필요에 따라 즉시 원하는 백엔드 클러스터로 트래픽을 보내고 끊을 수 있다. 

- 부하 테스트 : 신규 추가한 서비스 또는 백엔드에 트래픽을 점진적으로 증가하는 등의 방식으로 부하를 유발할 수 있다. 

- 트래픽 드랍(정확히는 Shedding) : 각 요청에 대해 제한된 이상의 요청이 발생한 경우 이를 드랍하는 방식을 사용할 수 있다. 

- 정적 응답 처리 : 특정 요청에 대해서는 백엔드로 트래픽을 보내는 대신 즉시 응답하도록 구성할 수 있다. 

- 멀티 리전 고가용성 : Zuul 은 받은 요청을 아마존 웹 서비스의 리전 레벨에서 분배할 수 있다.  


그리고 이와 같은 사용성을 기반으로 넷플릭스가 추가적으로 할 수 있는 일은 

- Test : 넷플릭스 규모의 마이크로 서비스 구성에서는 어떤 테스트는 반드시 프로덕션을 통해서만 가능한 경우가 발생한다. 이때 신규 서비스를 배포하고, 전체 트래픽 중 아주 일부의 트래픽만 이 테스트로 흘려 테스트를 수행하고 있다. 또는 이 개념을 조금 더 확장해서 Canary 테스트로 사용할 수도 있다. 배포 전 신규 버전의 서비스를 준비하고, 이 신버전으로 구버전을 대체하기 전에 동일한 요청에 대해 아주 작은 양의 트래픽만 신버전으로 흘린다. 로그를 모니터링 하고, 테스트를 통과하여 서비스에 문제가 없다는 것이 확인되면 트래픽의 비율을 조정한다. 자연스럽게 구버전으로 흐르는 트래픽은 감소하고 신버전은 증가하며, 구버전에 더 이상의 트래픽이 처리되지 않으면 모두 terminate 한다. 

https://github.com/Netflix/zuul/wiki/How-We-Use-Zuul-At-Netflix

이 외에도 SpringOne platform 에서 넷플릭스의 Zuul 담당 헤드가 다양한 내용을 소개해 주었다. 넷플릭스는 Zuul 을 사용하여 50개 이상의 ELB 로 트래픽을 분배하고, 3개의 아마존 웹 서비스 리전을 사용하고 있으며, 넷플릭스 서비스의 대부분의 트래픽을 처리하고 있다고 했다. 그리고 이 도구를 Edge-gateway 라고 부르고 있다. 혹시 infoq.com 계정이 있으신 분들은 Netflix 의 Zuul 매니저의 발표를 감상하실 수 있겠다. (https://www.infoq.com/presentations/netflix-gateway-zuul?utm_source=infoq&utm_medium=QCon_EarlyAccessVideos&utm_campaign=SpringOnePlatform2016)


넷플릭스가 공개하고 있는 Zuul 에 대한 정보는 아래의 링크에서 더 찾아 볼 수 있겠다. 

https://github.com/Netflix/zuul/wiki

https://github.com/Netflix/zuul/wiki/How-We-Use-Zuul-At-Netflix


이쯤 되면 나오는 이번 시리즈 단골 멘트. 스프링 클라우드에서는 이 마이크로 프락시를 사용하기 쉽게 제공하고 있다. 게다가 이전에 1, 2 시리즈를 통해 이미 소개한 유레카와 config 서버를 연계하여 사용하는 것이 가능하다. 백문이 불여일견, 백견이 불여일행. 우리의 사랑 START.SPRING.IO 로 접근하여 마이크로 서비스 구조를 만들어 보기로 한다. 다이어그램은 아래와 같다. 

오늘도 즐거운 발그림

Zuul proxy 의 동작만을 확인하는 간단한 코드는 spring cloud 프로젝트에서도 참조할 수 있으며, 블로그의 내용은 아래의 github 링크를 참조하면 되겠다. 간단한 데모이므로 별도의 암호화 처리등은 없다. 본 데모에서 가장 중요한 것은 온라인 설정의 업데이트, 유레카를 참조한 로드 밸런싱의 처리이다. 

https://github.com/younjinjeong/demo-config 

https://github.com/younjinjeong/spring-cloud-zuul-proxy-demo


Config server 구성 

- github.com 에 가서 신규 repository 를 만든다. (위의 demo-config 참조) 

- 애플리케이션의 properties 파일을 생성한다. : application.properties / helloworld-service.properties / helloworld-client.properties / discovery-service.properties   https://github.com/younjinjeong/demo-config 참조  

- bootstrap.properties 파일에 spring.cloud.config.uri 주소를 조정한다. 

- Config server 를 시작한다. 


Discovery-service 

- start.spring.io 에 접근한다. 

- artifact 에 discovery-service 

- dependencies 에 eureka server, config client 를 추가하고 프로젝트를 다운 받는다. 

- 설정은 demo-config 의 discovery-service 를 참조 


Helloworld-service 

- http://start.spring.io 로 접근한다. 

- artifact 에 helloworld-service 대신 더 상상력 넘치는 이름을 준다. 

- dependancies 에 web, rest repositories, actuator, actuator docs, config client, eureka discovery 를 적용한다. 

- Generate project 를 눌러 프로젝트 파일을 다운로드 받고, IDE 를 사용해서 연다. 아래와 같이 간단한 코드를 작성 한다. 

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@EnableEurekaClient
public class HelloworldServiceApplication {

public static void main(String[] args) {
SpringApplication.run(HelloworldServiceApplication.class, args);
}
}

@RefreshScope
@RestController
class MessageRestController {

@Value("${message}")
private String message;

@Value("${eureka.instance.metadataMap.instanceId}")
private String instanceId;

@RequestMapping("/")
String message() {
return this.message;
}

@RequestMapping("/id")
String instanceId() { return this.instanceId; }
}


Hellowworld-client : 실제 Zuul proxy 가 동작하는 구간이다. 보통 edge-service 라는 이름을 사용하기도 한다. 

- http://start.spring.io 로 접근한다. 

- artifact 에 helloworld-client 대신 더 상상력 넘치는 이름을 준다. 

- dependancies 에 Zuul, Config client, Discovery client, Ribbon 를 적용한다. 

- Generate project 를 눌러 프로젝트 파일을 다운로드 받고, IDE 를 사용해서 연다. 


Zuul Proxy 를 사용하기 위해서는 기본적으로는 어노테이션 추가외에 아무것도 할 일이 없다. 

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class HelloworldClientApplication {

public static void main(String[] args) {
SpringApplication.run(HelloworldClientApplication.class, args);
}
}

당연한 말이지만 라우팅 설정이 필요하다. 설정에 대한 내용은 demo-config 저장소의 helloworld-client.properties 을 살펴볼 필요가 있다. 아래의 설정을 살펴 보자. 

server.port=${PORT:9999}
info.component="Zuul Proxy"

endpoints.restart.enabled=true
endpoints.shutdown.enabled=true
endpoints.health.sensitive=false

zuul.ignored-services='*'
zuul.ignoredPatterns=/**/api/**

#route 규칙은 zuul.routes.스프링애플리케이션이름=path
zuul.routes.helloworld-service=/hello/**
zuul.routes.discovery-service=/eureka/**

ribbon.ConnectTimeout=3000
ribbon.ReadTimeout=60000


정리해 보면, 

- helloworld-service 는 백엔드 서비스로 동작한다. 두개의 RequestMap을 가지는데, 하나는 "/" 요청에 대해 설정 파일에 주어진 메세지를 응답하는 것이고, 다른 하나는 /id 로 현재 동작중인 인스턴스의 정보를 서버의 정보를 리턴한다. 즉, 동일한 애플리케이션을 로컬에서 서로 다른 포트로 동작하거나, 실제 클라우드에 배포하여 로드 밸런싱이 정상적으로 수행되는지 확인 할 수 있다. 

- helloworld-client 는 edge 서비스로서 zuul proxy 를 사용하고, 유레카를 통해 얻어진 백엔드 서버 정보를 기반으로 ribbon 을 사용하여 로드 밸런싱 한다. 

- 라우팅 규칙은  "zuul.routes.[유레카를통해 얻어진 spring.application.name]=경로" 로 구성된다. 

- 당연하지만 위에 설명한 기능을 제공하기 위한 더 많은 설정이 존재한다. 


Config Server, Discovery service, helloworld-service, helloworld-client 의 순서대로 애플리케이션을 구동한다. localhost:8000/ 으로 요청하여 서비스가 정상 동작 하는지 확인한다. 정상적이라면 Hello world! 를 볼 수 있다. 

$ curl http://localhost:8000/
Hello World!

먼저 서비스의 재시작 없이 설정을 변경하는 방법을 위의 메세지 처리를 통해 확인해 보자. demo-config/helloworld-service 에서 message 설정을 원하는 메세지로 변경한다. 변경했으면, 연결된 커밋, 푸시한다. 설정이 정상적으로 반영되었다면, Config 서버에서는 변경된 최신의 설정을 바로 참조하고 있으나 서비스에는 반영이 안된것을 확인할 수 있다. 아래의 주소로 접근하면 message 의 내용이 변경되었고 이를 config server 가 들고 있는것을 확인할 수 있다. 

http://localhost:8888/helloworld-service/default

{

},

서비스에 바로 반영되지 않는 것은 원래 그렇게 디자인 했기 때문이다. 설정이 변경될 때마다 자동으로 서비스에 반영하는 것은 위험할 수도 있으며, config server 에 부담을 주지 않기 위한 것도 있다. 서비스에 변경을 적용하려면, 지난번에 설명한 바와 같이 empty post 요청을 다음과 같이 전달하면 된다. 

$ curl -X POST http://localhost:8000/refresh
["message"]

정상적으로 동작했다면, 어떤 내용이 변경되어 반영됬는지 리턴될 것이다. 그럼 이제 백엔드 서비스로 다시 직접 요청해 보도록 하자. 

$ curl http://localhost:8000/
Spring Cloud is awesome!

이 동작이 의미하는 바는 무엇인가. 설정을 변경하고 프로세스 재시작, 재배포 이런 과정을 별도로 수행하지 않아도 변경된 설정이 동작중인 서비스에 즉각 반영할 수 있는 메커니즘이 있다는 것이다. 이러한 방법은 Config server / client 를 통해 동작하며 이는 당연하게도 Zuul proxy 의 라우팅 변경에도 사용할 수 있는 것이다. 즉, 신규 애플리케이션을 만들어 동작하고 있는 중이라면, 해당 애플리케이션으로의 트래픽을 서비스 재시작 없이 변경하거나 추가할 수 있다는 의미가 된다. 


이제 로드 밸런싱을 살펴보자. 포트 8000에서 동작하고 있는 서비스는 백엔드다. 그리고 Zuul 은 9999 포트에서 동작중이다. 그리고 오늘의 주제와 마찬가지로 Zuul 이 정상적으로 프락싱을 수행하고 있는지 확인해 보도록 하자. 위의 라우팅 규칙에 따르면, Zuul proxy 서버의 /hello 로 요청을 하게 되면 위의 메세지가 리턴 되어야 한다. 

$ curl http://localhost:9999/hello
Spring Cloud is awesome!

사실 helloworld-client 애플리케이션에 보면 뭐 한것도 없다. 그럼에도 불구하고 프락싱은 정상적으로 동작하고 있는 것이다. 이제 밸런싱을 확인해야 하는데, 위의 메세지는 설정 서버로 부터 동일하게 가져와 반영되는 것이므로 밸런싱이 정상적으로 동작하는지 확인하기가 쉽지 않다. 따라서 동일한 백엔드 서비스를 다른 포트로 동작하게 하고 실제 밸런싱이 되는지 확인해 보자. 아래의 커맨드를 사용하면 동일한 애플리케이션을 다른 포트로 구동할 수 있다. 

# helloworld-service 디렉토리로 이동하여 먼저 빌드를 수행한다 
PORT=8989 java -jar target/helloworld-service-0.0.1-SNAPSHOT.jar

유레카 서비스를 확인해 보면 새로 구동한 백엔드 서비스가 HELLOWORLD-SERVICE 애플리케이션으로 2개의 인스턴스에서 동작하고 있는 것을 확인할 수 있다. 


localhost:9999/hello/id 로 요청을 수행하면 서비스 이름:포트 정보가 나타나는데, 반복적으로 요청을 수행하면 8000 포트와 8989 포트가 번갈아 가며 나타난다. 즉, 정상적으로 로드 밸런싱이 수행되고 있는 것이다. 다시 8989로 동작중인 애플리케이션을 종료하게 되면 이는 즉시 밸런싱에서 제외되고 8000번만 나타난다. 이것은 무엇을 의미하는가. 바로 동적으로 멤버의 추가와 제거가 발생하고, 이 정보가 즉각 참조되어 서비스-인, 서비스-아웃을 수행할 수 있다는 것이다. 

이러한 사용성은 필요에 따라서 전세계에 위치한 데이터센터 중 내가 원하는 지역의 어디로든 트래픽을 동적으로 분산할 수 있는 유연성을 제공한다. 그리고 이런 동작은 그 어떤 프로세스의 재시작도 없이, 그 어떤 애플리케이션의 재배포도 없이 가능하다. 이런 구성이 바로 클라우드에서 동적으로 생성되고 삭제되는 각종 서비스와 그 서비스에 할당된 애플리케이션 인스턴스를 서비스에 사용하고 제거하는 "클라우드에 맞는" 방법인 것이다. 


금번 포스팅에서는 자세히 소개하지는 않겠지만, 이 Zuul 을 사용하여 필터를 적용할 수 있다. 필터는 클라이언트의 HTTP 요청을 받고 응답하는 과정에서 리퀘스트를 라우팅 하는 동안 어떤 액션을 수행할지에 대한 범위를 지정하는 역할을 한다. 아래는 아래는 몇가지 Zuul 의 필터에 대한 특징이다. 

- Type:  리퀘스트/리스폰스 라우팅 되는 동안 필터 적용 상태의 변경을 정의함 

- Execution order: Type 안에 적용되는, 여러개의 필터 적용 순서를 정의 

- Criteria: 순서대로 실행될 필터에 필요한 조건들 

- Action: Criteria, 즉 조건이 매칭하는 경우 수행할 액션 


필터에는 아래의 타입들이 존재한다. 

- PRE: 백엔드 서버로 라우팅 되기 전에 수행되는 필터. 예를 들어 요청에 대한 인증, 백엔드 서버의 선택, 로깅과 디버깅 정보 

- ROUTING: 요청을 백엔드로 라우팅을 제어할때 사용되는 필터. 이 필터를 통해 Apache HttpClient 또는 넷플릭스 Ribbon 을 사용하여 백엔드 서버로 요청을 라우팅 (본 블로그의 예제에서는 Ribbon 을 사용중) 

- POST: 백엔드 서버로 요청이 라우팅 되고 난 후에 수행되는 필터. 예를 들면 클라이언트로 보낼 응답에 스텐다드 HTTP 헤더를 추가한다던가, 각종 지표나 메트릭을 수집하거나 백엔드에서 클라이언트로 응답을 스트리밍 하는 것등. 

- ERROR: 위의 세 단계중 하나에서 에러가 발생하면 실행되는 필터 

Zuul 은 사용자에게 커스텀 필터 타입을 정의하고 사용할 수 있도록 한다. 따라서 특정 요청을 백엔드로 보내지 않고 바로 클라이언트에 응답을 수행하는것과 같은 구성이 가능하다. 넷플릭스에서는 이런 기능을 내부의 엔드포인트를 사용하여 Zuul 인스턴스의 디버그 데이터 수집에 사용하고 있다고 한다. 아래는 Zuul 내부에서의 요청이 어떤 흐름을 가지는지 보여주는 좋은 그림이다. 

https://github.com/Netflix/zuul/wiki/How-it-Works


스프링에서 Zuul 필터의 사용은 아래의 두 코드를 살펴 보자. 

먼저 com.netflix.zuul.ZuulFilter 를 익스텐드 해서 pre 필터를 생성한다. helloworld-client 애플리케이션에 아래의 파일을 추가한다.

spring-cloud-zuul-proxy-demo/helloworld-client/src/main/java/com/example/filters/pre/SimpleFilter.java

package com.example.filters.pre;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;

public class SimpleFilter extends ZuulFilter {

private static Logger log = LoggerFactory.getLogger(SimpleFilter.class);

@Override
public String filterType() {
return "pre";
}

@Override
public int filterOrder() {
return 1;
}

@Override
public boolean shouldFilter() {
return true;
}

@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();

log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));

return null;
}

}

- filterType() 은 필터의 타입을 String 으로 리턴한다. 이 경우 pre 이며, 만약 route 에 적용했다면 route 가 리턴된다. 

- filterOroder() 는 필터가 적용될 순서를 지정하는데 사용된다. 

- shouldFilter() 이 필터가 실행될 조건을 지정한다. 위의 설명에서 Criteria 부분 

- run() 필터가 할 일을 지정한다. 


spring-cloud-zuul-proxy-demo/helloworld-client/src/main/java/com/example/HelloworldClientApplication.java 

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import com.example.filters.pre.SimpleFilter;

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class HelloworldClientApplication {

public static void main(String[] args) {
SpringApplication.run(HelloworldClientApplication.class, args);
}

@Bean
public SimpleFilter simpleFilter() {
return new SimpleFilter();
}
}


curl http://localhost:9999/hello/id 로 요청을 해 보면, 아래와 같은 로그를 확인할 수 있다. 

2016-09-22 17:58:33.798  INFO 7307 --- [nio-9999-exec-6] com.example.filters.pre.SimpleFilter     : GET request to http://localhost:9999/hello/id


지금까지 소개한 3개의 도구, Config Server, Eureka, Zuul 의 세개는 모두 스프링 클라우드의 도구다. 스프링 클라우드에서는 클라우드에 맞는 서비스 연동을 제공하기 위해 이러한 넷플릭스 오픈소스들을 넷플릭스와 함께 만들고 있다. 이것은 시작일 뿐이며, 이 다음 번에는 서비스에 장애가 발생했을때 GET 요청을 처리할 수 있는 기법을 제공하는 Circuit breaker (Netflix Hystrix) 와 POST 메세지에 대해 고가용성의 방법으로 처리할 수 있는 방법에 대해 적어보도록 하겠다. 


이 Zuul 의 구조에 대해 더욱더 궁금하신 분들은 아래의 넷플릭스 블로그를 참조하시면 되겠다. 

http://techblog.netflix.com/2013/06/announcing-zuul-edge-service-in-cloud.html


추가로 Zuul 에 대해 더 관심이 있으신 분들 중 비밀 댓글로 이메일 주소를 적어주시는 5분께 금번 SpringOne Platform 에서 발표된 넷플릭스의 Zuul 사용에 대한 영상을 공유 할 수 있도록 하겠다. 유료 행사라 아직 전체 공개는 하지 않는 듯. (만약 공유가 잘 안되더라도 용서를.) 

https://www.infoq.com/presentations/netflix-gateway-zuul?utm_source=infoq&utm_medium=QCon_EarlyAccessVideos&utm_campaign=SpringOnePlatform2016


(정윤진, younjin.jeong@gmail.com) 


Open source serverless - what?!!

Techs


(younjin.jeong@gamil.com, 정윤진) 


이전에 AWS 에서 다닐때 했던 기획으로 10만원으로 월 10만명 사용자 받기 이런거를 해보자는 아이디어를 냈었다. 물론 아이디어를 내고 나서 퇴사하는 바람에 다른 분들이 다른 이름으로 진행 했었지만, 어쨌든 요는 무지 저렴하게 서비스를 구현해보자 라는 것이었고, 그러한 아키텍처의 중심에 '서버리스' 라고 불리는 즉 서버가 없이 구현하는 아키텍처를 그렸다. 물론 샘플로 동작하는 코드도 쓰다가 말았지만 ㅋ. 


이것이 제공하는 장점은 크게 두가지로 보는데, 하나는 '내가 관리해야 할 인프라가 별도로 없다' 라는 것이고, 두번째는 '비용이 무지막지하게 저렴하다' 라는 것이다. 그리고 이는 스타트업과 같이 사람과 돈이 귀한 조직에서 엄청난 반향을 일으키고 있다. 이 '서버리스' 아키텍처는 Lambda 를 통해 비로소 완서이 된다. 많은 사람들이 AWS 의 다른 서비스인 API Gateway 와 연동하거나, S3, Kinesis 와 같은 다른 AWS 서비스로 부터 이벤트를 받아 트리거링 되어 동작하도록 구성한다. Lambda 는 서비스가 지원하는 몇가지 언어를 사용해 코드를 만들어 올리면 이벤트에 의해 트리거 되어 60초간 해당 코드를 실행할 수 있는 일종의 플랫폼으로 보면 된다. 가격 역시 100ms 단위로 과금하기 때문에 시간당 과금하는 버추얼 머신보다 저렴하게 사용할 수 있다고 설명되는 것이 일반적이다. 



금일 소개할 내용은 바로 이 Lambda 와 유사한 형태의 도구를 오픈소스로 동작할 수 있는 새로운 것이 나타나서 포스팅한다. 단, 이것에 대해 프로덕션 도입을 하는 것은 현재로서는 추천하지 않는다. 또한 서버리스는 개인적으로 CSP 에서 제공하는 또 다른 형태의 플랫폼이고, 이것은 보통 규모의 경제를 확립한 서비스 제공자에 의해 제공이 될때 가격적 잇점이 발생할 수 있다는 점 또한 잊어서는 안된다. 많은 이들이 동의하는, 또 개인적으로도 동의하는 생각은, 서버리스 자체는 일종의 다커 신드롬과 무엇이 다른가 뭐 그런 의견이 있다. 


요약하면, 현재 인기 있거나, 인기를 얻을 가능성이 있는 도구들은 거의 대부분 인프라에 대한 별도의 작업 없이 코드를 빠르게 배포하려는 것들이며, 수많은 도구 중 하나로, 우왕 Lambda 가 오픈소스로? 이런게 나왔네 정도의 느낌으로 보시는게. 


아무리 봐도 엔터프라이즈 레벨에 당장 사용 가능한 도구는 Cloud Foundry 가 유일한듯. (기승전피) 



https://blog.leveros.com/introducing-lever-os-d10a857f210e#.dd2qiwcvz 


서버레스 컴퓨팅이 뜨거운 감자가 된지는 좀 되었다. 그리고 이게 왜 뜨거운 감자인지 알게되는건 그다지 어렵지 않다. 클라우드 기반의 애프리케이션 개발에 대한 요구는 나날이 늘어만 가고 있는데, 실제 이 요구를 수용할 수 있는 DevOps 는 시장에 많지 않다. Stack Overflow 의 설문에 의하면 개발자 대 DevOps 의 비율이 30:1 에 달한다고 한다. 다른 데이터에서는 더 심한게 70:1 이라고 말하는 곳도 있다. 어쨌든지 맞건 틀리건 간에 이런 지표들은 두 직군의 기술의 격차, 그리고 그때 그때 발생하는 운영 업무에 대한 트렌드를 보여준다고 생각한다. 


서버리스 컨셉은 이러한 문제를 해결하는데, 왜냐면 애플리케이션을 확장성 있게 개발하고 배포하는데 별도의 DevOps 가 필요 없기 때문이다. 하지만 이런 기술은 오로지 AWS, Azure, Google Cloud Platform 과 같은 클라우드 서비스 공급자에 의해서만 사용이 가능했었는데, 이는 당연하게도 해당 클라우드 서비스 공급자에 대한 락인, 그리고 로컬 머신이나 로컬 데이터센터에서는 사용할 수 없다는 문제가 있다. 


... 지금까지는. 



Lever OS 소개 


(해당 블로그에서 가져온 글이므로) 우리는 오늘 Lever OS 버전 0.1 을 발표하게 되어 매우 기쁘다. Lever OS는 오픈소스 서버리스 플랫폼으로, DevOps 가 없이도 마이크로 서비스 구조의 백엔드를 개발하고 배포할 수 있는 도구다. 이는 복잡한 인프라 구성에서 개발자들을 자유롭게 하고, 확장에 대해 투명한 뷰를 제공하는 강력한 빌딩 블록을 제공한다. 


Lever OS를 사용하면, 서버에 대해 생각할 필요가 없다. 서비스에 대해서만 생각하면 된다. Lever 는 코드를 인스턴스에 적재하여 요청에 따라 가능한 많은 노드에서 구동한다. 또한 라우팅과 로드밸런싱 트래픽을 투명하게 처리해 주기 때문에 별도의 컴파일된 리버스 프락시를 사용할 필요가 없다. 다 들어있기 때문에. 





복잡한 백엔드의 형태를 지원하기 위해 다양한 레이어를 구성하는 것도 가능하다. 각각의 서비스를 서로 다른 팀들에게 관리하도록 함으로서 다른 서비스들에 대한 서로의 책임을 한계적으로 명시할 수 있다. 또한 이 모든 것들은 내장되어 있는 RPC 시스템을 통해 연동할 수 있겠다. 



각가의 서비스는 소규모의 export function 으로 개발되어 Lever 위에 배포할 수 있다. 자바스크립트를 예로 들면, .js 파일에 export function 을 지정하고 Lever 에게 해당 자바스크립트 파일을 지정하는 형태로 동작한다. 그리고 이 function 은 서비스의 API 가 될 것이며, HTTP 를 사용하여 트리거 되어 동작한다. 


또한 Lever OS 는 오픈소스이기 때문에 이를 랩탑에서 사용할 수도 있다. 따라서 다른 서버리스 도구들과 다르게 매번 클라우드에 배포할 필요가 없어지기 때문에 로컬에서 매우 빠르게 개발 및 테스트 사이클을 사용할 수가 있다. 이렇게 개발된 코드는 일관성을 제공하기 때문에, '내 머신에서는 돌아갔는데' 타입의 버그에 대해서도 자유로울 수 있다.  



간단한 예제 코드 


"Hello, <name>!". 을 응답하는 백엔드 서비스를 만든다고 치자. Lever OS 에서는 해당 문자열을 리턴하는 JS function 을 하나 만들고 간단한 설정 파일을 구성하면 된다. 



 



배포는 다음의 커맨드로. 


$ lever deploy



이게 전부다. 이제 이 서비스를 아래의 영상에서와 같이 다양한 방법으로 호출해서 사용할 수 있다. 



본 도구에 대해서 더 궁금하다면, Lever OS 의 GitHub 페이지에 들러보면 되겠다. 


이는 Lever OS 의 최초 릴리즈다. 따라서 우리는 앞으로도 지속적으로 개선할 것이며, 이 개선에 중요한 것은 여러분의 피드백이다. 아울러 현재로서는 베타 상태이며, 문제를 경험한다면 Github 이슈 페이지에 등록해 주기 바란다. 



(younjin.jeong@gmail.com, 정윤진) 




Cloud, HPC, GPU

Techs
( younjin.jeong@gmail.com , 정윤진)

들어가기에 앞서, 각 1, 2 와 같은 내용의 구분은 별 의미 없으며, 내용이 길어 고개 하나 넘고 쉬어가라는 의미에서 넘버링 하였음을 알린다. 으음.. 그리고 일부러 중간중간 그림을 많이 넣었는데 읽는데 방해가 될 수 있음을 인지 하시라.
물론, 당연히 관심있는 분들만 읽어주시길.


누구냐..넌!


Image from : http://t3.gstatic.com/images?q=tbn:ANd9GcQp63GW_-iGDkvhIJKN5vpXJpA8VBJ0ulVKi9rZyQ7uoSat2OXj&t=1

1

기존의 전통적인 인프라들은 정말로 많은 요구사항들을 충족해 왔다. 거대했던 메인프레임들은 크레이가 만들어 내는 수퍼컴퓨터의 발전을 가져왔으며, 피씨와 인터넷, 인트라넷의 눈부신 발전은 리눅스의 등장과, 이 리눅스로 만들어내는 기존의 수퍼컴퓨팅의 아성을 뛰어넘는 수퍼컴퓨팅의 또 다른 형태, 클러스터링을 발전시켜왔다.

돈없어서_이러는거_아님.jpg


Image from : http://www.clustercompute.com/images/image4.jpg


10년전, 이제 막 Jazz 나 당대 최고의 그래픽 카드인 Matrox 제품군들을 뒤로하고 3D 그래픽 카드들이 보급되기 시작했다. 이들은 게임의 발전과 함께 피씨 시장에서 늘 주요한 구성품목으로 자리잡아 왔으며, 기존의 해상도와 색 표현력을 위시한 2D의 세상을 넘어 화려하고 아름다운 3D 세상을 열게된다. 퀘이크, 언리얼 등의 인기있는 3D 기반 게임의 엔진들이 게임시장의 중요한 위치를 선점하게 되었고, 이러한 게임 및 게임에 사용되는 3D 영상의 제작을 위해 사용되는 쿼드로같은 그래픽카드들은 디자이너가 사용하는 워크스테이션에 붙어 엄청난 프리미엄의 가격과 함께 날개돋친듯 팔려나갔다. 이제는 그저 보급형 PC의 메인보드에 붙어있는 그래픽 칩셋조차 3D 가속을 처리하는 별도의 GPU를 가지고 있으며, 보다 나은 영상의 게임을 즐기고자 하는 게이머들에 의해 GPU를 중심으로한 그래픽 카드 산업은 어마어마하게 발전하여 현재에 이르렀다.

아아... 그시절의 클라우드 ㅠㅠ

Image From : http://premium.uploadit.org/dem2001/ff7epsxe01.JPG
(당시 3D 그래픽 카드가 없으면 분당 5프레임의 지옥을 경험해야 했다. 사진은 10여년 전의 Final Fantasy VII)

5년전 즈음 분자화학식의 계산을 위한 컴퓨팅에 GPU를 사용하는 라이브러리를 만들어 보자는, 당시로서는 세계적으로도 그다지 발전하지 못한 부분에 관심을 두었던 자그마한 회사의 제의가 있었다. 결국 지금 그 회사는 없지만, 그 당시의 아이디어는 이제 현실이되어 우리들이 쉽게 접하지는 못하는 분야에 널리 깔려있다. GPU가 CPU보다 부동소수점 연산이 뛰어나다는 사실은 굳이 여기서 언급하지 않더라도 많이들 알고 계시리라 믿는다.

한때 프로세서의 FPU (Floating Pint Unit, 부동소수점 처리장치)의 성능이 중요했던 시기가 있다. 아마도 펜티엄 프로, MMX 등의 인텔 기반 CPU 가 등장하던 시기였던 듯 한데, 이 제품들은 부동소수점 연산의 처리능력을 MIPs 수치와 함께 병렬 프로세싱이 가능한 형태의 SIMD 와 패키징하여 프로세서를 홍보하던 시절이 있다. 지금의 멀티 코어 시대에서는 사실 별 것 아닌것 같아 보이지만, 9년 전만 하더라도 이러한 프로세서를 2개 이상 박을 수 있는 메인보드와 걸출한 성능의 GPU를 가진 그래픽 카드, 4기가 정도의 램을 가진 워크스테이션은 모든 그래픽 하는 사람들, 또는 서버에 관심있었던 사람들에게 꿈의 머신이었다.(당시에는 64비트가 범용적이지 않았다) 조금 더 하자면 SCSI 를 사용하여 I/O 프로세싱을 CPU를 사용하지 않도록 하는 부분까지 추가하게 된다면, 당시의 물가에도 돈 500은 수월하게 깨졌으니까.

지난 시절을 회상하고자 이렇게 길게 서두를 뽑은건 아니다. 이제는 컴퓨팅 클라우드 이야기를 해 보자.



2

컴퓨팅 클라우드, 즉, 일반 서버의 기능을 클라우드에서 누려보자 하는 서버 인프라 그 자체를 클라우드로 제공하는 개념의 컴퓨팅 클라우드는, 사실 그 사용의 범위가 일반적인 웹 서비스를 사용하기 위한 용도 이상으로서 활용하기에는 쉽지 않다. 물론 현대의 거의 모든 고객 요구사항은 웹을 통해 이루어지고, 기존 웹의 3계층 구조(3계층 아니라고 따지지 말자. 잘 알지만 주제가 아니다.)를 어떻게 클라우드에 잘 반영하고 마이그레이션 해 내느냐에 따라 클라우드의 비용에 대한 효율성, 신축성이 이야기 될 수 있을 것이다. 이에 맞는 웹 어플리케이션의 설계도 중요한 과제지만, 이러한 내용은 이 포스팅의 주제는 아니다.

이러한 일반적인 컴퓨팅 클라우드를 HPC의 사용에 도입하려는 시도가 일부 있다. High Performance Computing 이라 불리는 이 수퍼컴퓨팅의 한 분야는, 사실 R&D를 하고자 하는 기반 기술을 가진 어떠한 기업이라도 관심이 있을법한 중요한 하나의 카테고리이다. 이 부분은 모든 산업의 기반이 되는 산업들에서 더욱 중요하게 취급된다. 예를 들면, 지금 손에 들고있을 일회용 재생 플라스틱 커피용기라던가, 지금 보고있는 모니터의 각 플라스틱 부품의 성분들, 또는 여러분의 몸이 지니고 있는 DNA등과 관계된 모든 산업의 기반 기술인 화학, 생물학, 유체역학, 이론물리학, 공기역학 더하여 양자역학등 모든 기초과학의 분야에 아주 필요한 기술이 IT에 들어오면 이러한 HPC 라는 분야가 되는것이다. 대다수는 이런 기술과 상관없다고 생각하겠지만, 타이어를 만드는 회사는 타이어의 원료인 고무를 어디서 구매한 어떤 재료와 어떻게 연소시켜 얼마만큼의 효율로 타이어를 생산해 낼 수 있는지는 매우 중요한 문제이다.  또는, 정유회사에서 어느 지역의 원유를 가져다가 어떻게 정제하여 어떤 비율로 고급유, 무연휘발유, 경유, 백등유 등을 얻어낼 수 있는지 역시 생산가와 소비자가를 가늠짓는 매우 중요한 요소가 된다. 물론, 이러한 가격들은 여러분이 실제로 비용을 지불하는데 아주많이 직접적인 영향을 끼치게 된다. 

요딴거의 계산에 쓰인다는 말

Image from : http://www.photon.t.u-tokyo.ac.jp/~maruyama/kikan2002/clustering.gif


문제는 이러한 부분에 필요한 계산들, 분자화학식을 계산해 내는 시스템을 준비하는것은 어마어마한 규모의 자금을 가지고 있는 회사, 또는 연구 단체가 아니면 불가능하다. 아니, 클라우드 컴퓨팅 이전에는 불가능 했다. 실제로 현재 국내의 각 대학들 중에서는 이러한 시스템들을 "베오울프" 프로젝트 이상으로 구비하고 있는 장소는 많지 않을 것이며, 일부 보유하고 있더라도 세월의 흐름에따라 그 성능이 현대의 기술이 요구하는 데이터량에 미치지 못할 가능성도 높다. R&D 분야가 언제나 그렇듯이, 항상 많은 돈이 들고 시간에 촉박하며 누가 먼저 깃발을 꼽고 특허를 따 내느냐가 중요한 부분이며, 따라서 이러한 부분의 지원을 위한 HPC 환경의 필요성은 기초과학이 필요한 모든 분야에 매우 중요하게 되는 것이다.

이런 부분에 종사하는 분들의 클라우드에 대한 관심이 높을것 같지만, 사실 나는 반대라고 본다. 이미 이 분야는 병렬 컴퓨팅의 끝이다. 현재 국내의 IT 분야에 종사하는 그 어느 누구보다, 물리엔진을 설계하는 분들을 제외하고는 이미 밥먹고 수학과 물리와 화학만 하시는 분들이 이런 HPC를 사용한 분산 컴퓨팅 환경에 익숙하다. 다량의 노드에 일종의 메타 데이터 형태인 계산식을 넣고 큐에 뿌리면, 배치 시스템은 이를 계산노드, 즉 컴퓨팅 노드에 뿌려서 분산시켜 계산하고 그 결과를 얻어내고, 다시 모아서 데이터베이스 또는 필요한 데이터 형태로 바꾸어 스토리지에 넣는다. 최근의 클라우드 컴퓨팅에 익숙하신 분이라면 잘 알고 있을 Map/Reduce 의 구성은 이미 이 분야에서 오래전 부터 사용해 왔던 기술들인 것이다. 그렇기에, 일반 CPU만을 게스트에 쪼개어 사용하는 형태의 구성은 만약 그 계산이 빡세게 돌아가는 분야라면, 그다지 매력적으로 들리지는 않을 것이다. 하지만, 클라우드가 구현하고 있는 클러스터링의 방식은, HPC의 요구사항과 딱 맞아 떨어지는 것이 사실이며, 여기에 GPGPU와 같은 기능을 부여한 VM이 클라우드에서 제공된다면 이제 이야기는 달라진다.  두둥.



3

상황이 이럴진데, HPC의 요구사항을 반영한 클라우드의 서비스가 생기지 않을리 없다. 이들은 일반 컴퓨팅 클라우드 서비스보다는 그 수요가 낮지만 높은 비용을 과금 할 수 있기 때문에, 전략적으로 시장의 수요를 잘 예측하고 공급한다면 클라우드 서비스 공급자 입장에서는 제품의 다양화를 꾀할 수 있기에 분명 매력적이다. 그리고 연구 개발 기관에서는, 수많은 서버를 직접 구매하는 대신 필요할때 공급자로 부터 컴퓨팅 노드를 "빌려서"사용할 수 있기에 원래 할 수 없었던 것이 "가능" 해 지며, "저렴" 하다고 느끼게 된다. 물론 한국은 그 기초과학의 수요가 낮은 만큼 그 시장이 미국이나 일본만큼 크지는 않을 것이다.  하지만, 그 어느 기업이 이런 R&D 분야에 뒤떨어 지고 싶을까?

많은 기업이 보안상의 이유로 인하여 클라우드를 그들의 환경안에 자체적으로 구축하고 싶어할 수 있다. 일반적인 웹 서비스는 R&D 분야보다 그 보안성이 뛰어나다고 말하긴 힘들다. 분명하진 않겠지만 Shell 과 같은 국제적 원료기업은 이러한 전산화된 부분의 지원에 Aspen 등의 기업이 만들어낸 특수한 소프트웨어와 인재를 사용한다. 수십만 배럴의 원유를 구매하여 제품 생산 비율을 1% 이상이라도 높이려는 기업의 노력은 그 비용면에서 합당하다. 따라서 그들은 그 비용의 규모에 맞는 시스템들을 구비하여 제품의 개발에 사용하며, 그것이 클라우드 기반이던, 아니면 물리적 수퍼컴퓨팅의 클러스터링 환경이건 그에 걸맞는 규모로 경쟁사들과 치열하게 경쟁하고 있음이 분명하다.

Image From: http://www.sodahead.com/living/whats-your-fantasy-gift-this-year/question-1377465/

삼천포로 빠졌다.  따라서, 많은 기업이나 연구기관, 대학등은 아마도 그들의 전산실의 기존 자산 또는 일반적으로 쉽게 구할 수 있는 저렴한 하드웨어 (Commodity Hardware)를 사용하여 이러한 HPC 환경을 만들고 싶을 것이다. 본질적으로 이러한 부분에 굳이 가상화를 사용할 필요는 없지만, 또는 가상화를 써서 굳이 계산 속도를 떨어뜨릴 필요는 없겠지만, 중요한 것은 바로 "서로 다른 분야" 의 합목적성 때문에 가상화를 기반으로 한 일반적 컴퓨팅 클라우드의 모델을 도입하는것이 보다 이익이 될 수 있다는 점이다.

대학을 기준으로 이야기 해 보자. 대학에는 생물학과, 물리학과, 뭐 심지어는 자동차 학과에서의 충돌 계산을 위해서라도 이러한 HPC 환경이 필요하게 된다. 하지만 이 모든 학과를 위해 전산실에 HPC를 각각 구성해 주는 것은 아무래도 비용면에서 아리송 하게 된다. 아마도 행정담당은 "야 그거 그냥 걔네꺼 같이 쓰면 안돼?" 의 카운터 펀치를 날릴 것이 거의 확실하다고 본다. 이러한 환경에, 가상화를 사용한 클라우드의 구조를 가져다가 구성하되, 이 각각의 VM들이 GPU를 통한 연산을 수행할 수 있는 컴퓨팅 노드의 구조를 가진다면 어떨까? 물리학과는 그들이 필요한 기본 배치 시스템과 이런 배치 시스템과의 연동이 구성된 그들만의 소프트웨어/라이브러리를 설치한 이미지를 만들어 두고, 필요할 때 필요한 수량만큼 인스턴스를 생성하여 작업하고 또 계산이 끝난 다음 인스턴스를 삭제해 버린다면, 기존의 고정된 물리적 환경보다는 그 유연성이 높지 않을까?

이 연장선 상에서, 나는 각각의 HPC 의 형태가 요구하는 시스템의 구성이 서로 많이 다르지 않음을 알게 되었다. 드림웍스가 쿵푸팬더를 만들기 위해 사용했던 렌더 팜이나, MPICH2 라이브러리를 사용하여 계산식을 처리하는 시스템이나, Q-Chem이나 PC_GMESS, Gaussian 을 사용하는 화학식 계산에 필요한 인프라들의 구성은 비용 합리성 측면에서 그 컴퓨팅 노드로 사용될 일반적인 하드웨어의 형태가 크게 다르지 않다. 또한 이들에 필요한 네트워크 인프라의 요구사항도 거의 대동소이 하다. 이러한 시스템에서는 웹의 REST 구조와 같은 특수한 구성은 그다지 의미가 없으며, 전통적인 수퍼컴퓨팅에서 사용되던 잡/큐/배치/매니지먼트 시스템, 그리고 각 연구형태에 맞는 소프트웨어가 설치된 컴퓨팅 노드일 뿐이기 때문이다.

이러한 인프라의 아키텍처가 비슷하다는 점은, 다수의 사용자에게 동일한 물리적 인프라를 통해 가상화로 서비스하게 될 경우 많은 잇점을 가져다 줄 수 있다는 의미가 된다.

여러분이 만약 CUDA를 사용한 무언가를 만들고 있다면, 이러한 효과는 배가 될 것이다.  그런데, 이런 생각을 과연 나만 하는 것일까?  당연히, 아니다.  이런 분야를 노리고, 이러한 환경으로 구성된 클라우드가 이미 실재한다. 다음의 업체들이 바로 그들이다.

  • Amazon
  • NIMBIX
  • peer1 hosting
  • Penguin Computing
궁금하신 분들은 직접 검색해 보면 많은 정보를 얻을 수 있을 것이다. 또는, 다음의 링크를 참조하셔도 좋다.
http://www.nvidia.com/object/gpu-cloud-computing-service.html

링크에서 볼 수 있듯이, 이들은 모두 NVIDA의 Tesla 기술을 사용한다. 이 Tesla 기술이 적용된 하드웨어들은 다음의 링크에서 확인이 가능하다.
http://www.nvidia.com/object/preconfigured-clusters.html



4

단일 노드에서 리눅스를 기반으로 한 Tesla 기술이 반영된 장치를 붙인 물리적 머신을 구성하는 것은 어렵지는 않다. 다만, 이를 "가상화" 하고, 가상화된 VM 안에서 이를 CUDA를 사용하여 장치에 엑세스 하게 하는것은 쉽지 않다. 이는 GPU에 대한 Passthrough를 하이퍼바이저에서 지원해야 하고, GPU에서 SLI Multi-OS 가 가용해야 한다는 조건이 충족되어야 한다. Para Virtualization 형태로의 지원은 아직까지는 힘들어 보이며, Full Virtualization을 사용해여 일부 구현이 가능하다. Citrix Xen 5.6 에서 이를 지원하기는 하지만 실제 내손으로 테스트 해 본적은 아직 없다.

꽤_비싼_워크스테이션.jpg

Image From: http://www.microway.com/images/Octoputer_Tesla1000px.png


Citrix 에서 XenServer 5.6 부터 지원하는 방법은, Multi-GPU 를 가진 일부 GPGPU 장치의 각 GPU를 개별 가상 머신에 1:1 로 할당하는 방식으로서, 가상머신에서 GPU로의 직접적인 접근을 허용한다. 이는 Multi-GPU Passthrough 로서, 일반적인 VT 기술과는 달리 Full Virtualization 을 사용하여 하드웨어 리소스를 가상머신에 직접 할당함을 의미한다. Citrix는 윈도우 게스트에서 HDX 3D Pro 에서 제공하는 코덱을 사용하여야 제대로 사용 할 수 있다고 말하고 있으며, 리눅스 게스트에도 이러한 직접 엑세스는 제공하지만 아직까지 코덱을 별도로 제공하고 있지는 않는다고 설명한다. 현재 가용한 하이퍼바이저가 Citrix Xen이 유일하기 때문에, 아마존이 HPC 클라우드의 구성에 Xen을 사용했다는 말이 심심치 않게 들린다. PCI Passthrough 에 대해 궁금하신 분들은 맨 아래의 링크를 참조하시라. 역시 이런 문서는 IBM이 잘만든다.

아무튼, 이런 환경의 구성을 위해서는 관련 정보의 양과 하드웨어의 선정, 하이퍼바이저의 선정이 매우 중요하다. 물론 이들은 일반적인 클라우드를 구성할때도 중요한 내용이긴 하지만, GPGPU를 사용한 클라우드에서는 이런 요구사항이 충족되지 않으면 자칫 서비스 자체를 구성하지 못하게 될 가능성도 있기 때문에, 또한 아직까지는 범용 기술이 아니기 때문에 매우 주의를 요한다. 대단위의 서버를 구매하기 전에 가용성을 테스트 하기위한 방법에서는, 적어도 2대이상의 머신을 기반으로 시작해야 할 것이다.


가상화가 굳이 필요할지에 대해서는 각 기관이나 단체별로 의문을 제기 할 수 있겠지만, 일반적인 컴퓨팅 클라우드의 사용성을 위해서라도(굳이 HPC로 사용되지 않더라도) 가급적이면 가상화를 구현하는 것이 좋을 수 있다. 다만 Shared Storage를 사용하는 형태를 고집할 필요는 전혀 없으며, 오히려 스크래치를 위한 로컬 디스크가 중요하게 고려 되어야 한다. 이러한 HPC가 요구하는 그야말로 고성능의 조건에 부합하기 위해서는, 가상화를 하더라도 그 가상화의 비율이 일반 컴퓨팅 클라우드 보다는 현저히 낮을 것이라는 점이다. 이는 I/O에 대한 요구사항과 게스트OS가 많아지면 많아질 수록 계산 자체가 느려질 확율이 있기때문에, 게스트 OS가 많아지면 많아질 수록 Full Virtualization 을 사용해야 하는 강제성으로 인해 그 성능의 저하가 심각해 질 것이기 때문이다. 잊지말아야 할 점은, 컴퓨팅 클라우드는 원래 대부분의 시간동안 Idle 상태인 시스템 자원을 가급적이면 높게 사용하도록 분할하자는 취지였지만, HPC의 경우 계산을 하는 대부분의 시간동안 Idle 상태 따위는 없을 것이기 때문이다.  이러한 HPC만의 고사양에 대한 요구가 클라우드에서 어떻게 반영되었는지는 다음의 아마존 HPC 인스턴스 오퍼링에서 확인 할 수 있다.

The Cluster Compute instance family currently contains a single instance type, the Cluster Compute Quadruple Extra Large with the following specifications:

23 GB of memory
33.5 EC2 Compute Units (2 x Intel Xeon X5570, quad-core “Nehalem” architecture)
1690 GB of instance storage
64-bit platform
I/O Performance: Very High (10 Gigabit Ethernet)
API name: cc1.4xlarge

The Cluster GPU instance family currently contains a single instance type, the Cluster GPU Quadruple Extra Large with the following specifications:

22 GB of memory
33.5 EC2 Compute Units (2 x Intel Xeon X5570, quad-core “Nehalem” architecture)
2 x NVIDIA Tesla “Fermi” M2050 GPUs
1690 GB of instance storage
64-bit platform
I/O Performance: Very High (10 Gigabit Ethernet)
API name: cg1.4xlarge

일반적인 하드웨어에서, 48GB 이상의 메모리를 넣는것은 쉽지 않다. 따라서 위와 같은 아마존의 오퍼링을 두고 살짜쿵 추리를 해 보자면, Multi-OS 지원이 가능한 SLI 형태의 GPGPU가 최소한 2개 이상이며, 48기가의 메모리와 10G 이더넷 인터페이스를 가진 하나의 물리적 머신으로 2대 정도의 게스트를 수용한다고 볼 수 있겟다. 그냥 경험에 비추어 볼때 쿼드코어 2개 정도의 프로세서에서 이러한 고성능의 I/O를 지원하기 위해서는, 3개 이상의 게스트를 수용하는 것은 하드웨어 비용과 조합의 측면에서 맞지 않아 보인다. 아무리 GPU가 계산의 많은 부분을 담당하더라도 CPU와 Ram이 노는 건 아니기 때문이다. 아니면, 4개의 GPGPU를 가지고 대당 4개의 게스트 OS를 지원할 가능성도 있기는 하다. 이럴때의 물리 서버 대당 비용은 이미 Commodity HW라고 말하기 어려운 정도의 비용이 된다. 2U 서버를 Full 랙에 한 8칸 비우고 꽉 채운다고 가정하면 대략 17대, 10G 스위치가 24포트 하나에, 랙당 가용한 전력이 보통 미국이니까 100V 15A 정도라면....  아.. 직업병 나왔다. 암튼 뭐, 실제 정확한 구성은 아마존 엔지니어만이 알겠지만, 적절한 가격 선상에서 대략 2U서버하나에 전술한 바와 같은 서버를 적절한 양으로 구성한 것으로 보인다.


아무튼 이러한 점은 Private 클라우드를 구현하려는 기업이나 HPC 클라우드를 공급하는 기업 모두가 신중하게 고민해야 할 부분이기도 하다. HPC는 배치시스템을 통해 서로 다른 계산을 꾸준히 큐에 넣어 지속적으로 돌려줄 때 의미가 있다. 필름회사가 렌더팜을 직접 구성하게 된다면, 이는 자신들의 필름을 위한 렌더링이 끝나게 되면 이 비싼 시스템이 100% 놀아야 하게되는 단점이 있는 것이다. 따라서 지속적인 요구 사항이 있는 경우가 아니면, 이런 방법을 사용하여 직접 시스템을 구축하는것은 대단한 자산의 감소를 불러올 수 있음을 인지해야 한다.


HPC의 특성상, 클라우드의 가상화 개념 대신 자동화를 사용하여 구성 하는것도 가능할 것이다. 마치 필요한 OS를 수분만에 갈아치울 수 있는 노턴의 고스트와 같이, 필요한 때에 대상 머신을 순식간에 필요한 형태로 갈아 치우는 것은 이러한 가상화를 도입 하던지 하지 않던지 중요하다. 가상화를 사용하면 템플릿이나 이미지를 통해 비슷한 기능을 수행 할 수 있을 것이지만 아마도 자동화 도구 없이는 좀 뻑뻑할 것이다. 하지만 이런 자동화 만으로 HPC를 구성해서 고객에게 할당 하는 것은, 아무래도 그 사용성이나 서비스의 관리면에서 기존의 호스팅 환경과 다를바가 없게 된다. 즉, 가상화 없이 이러한 컴퓨팅 환경은 유연성이 떨어진다는 말이 된다.

국내에서 CUDA를 활용한 HPC가 현재 얼마나 필요한지는 모르겠다. 하지만 중요한 것은, 이 HPC가 가지는 기능성이 굳이 GPGPU를 통해서만 고비용을 들여 확인 해 볼 것이 아니라, 여러분이 수행중인 일반적인 계산을 위한 컴퓨팅 환경을 필요한 경우 기존의 컴퓨팅 클라우드에 적용해 시험해 보는것이 반드시 필요할 것이다. 만약 이에 대한 결과가 충분히 합리적인 것이라면, 굳이 이런 시스템을 자사에 구현 하거나, 또는 Private 클라우드에 굳이 Tesla 기술을 도입하여 고비용으로 구축할 필요는 없을 것이다. 아니면, 위의 아마존의 예에서 처럼 HPC만을 위해서라면 게스트 OS의 오케스트레이션에서 물리적 서버당 가상화 서버의 비율을 낮추는 방향으로 요구를 충족시키는 방법도 있을 수 있다. 아무튼 중요한것은, 필요한 소프트웨어의 성능을 KT 클라우드나 아마존 클라우드 인스턴스 또는 구성하고자 하는 Private Cloud에 사용될 컴퓨팅 노드의 가상화를 사용하여 환경을 구성하여 테스트 하는 것이다.


쿵푸팬터2를 예로 들면, 약 56만개의 프로세서가 있어야 1시간 안에 렌더링을 마칠 수 있다고 한다. 사실 이런 규모의 프로세서를 직접 구매한다는건 거의 미친짓에 가깝기 때문에, 렌더링에 필요한 클러스터 환경을 클라우드에 구성하고, 인스턴스를 약 100여개 정도 생성한 후에 샘플 테스트로 나오는 결과값을 추려보면 얼마의 비용이 필요한지, 얼마의 시간이 필요한지에 대한 챠트를 구성해 볼 수 있을 것이다.  이를 실제 물리 머신 또는 Tesla 머신에 적용해 보고 나오는 시간과 비교했을때의 결과가 합리적이라면, 여러분은 동일한 작업을 수행하기 위해 필요한것이 무엇인지 알게 될 것이다.

Time vs Money

Image from: http://www.dollarthug.com/wp-content/uploads/2010/05/time-vs-money.jpg


5

어쨌든, CPU 보다 GPU를 중점적으로 사용하는 컴퓨팅 환경은 엄청난 매력이 아닐 수 없다. 또한 이를 가상화 하여, 클라우드로서의 사용성을 부여하게 된다면 이는 그야말로 대다수의 기업에게는 눈이 번쩍 뜨이는 달콤한 기술이 될 것임에 분명하다. 하지만, 그 사용 목적성을 생각해 보면 아마존과 같은 퍼블릭 클라우드의 형태 보다는, 각 기업에서 스스로 이를 구축하여 사용하고자 하는 요구가 더 높을 것이다. 이러한 요구사항들에 비추어, 반드시 GPGPU를 사용한 클라우드 환경의 구성이 필요하다면, 다음의 내용을 중요하게 고려해야 할 것이다.

  • 사용중인 어플리케이션의 CUDA 지원 여부
  • 하이퍼바이저의 Multi-GPU Passthrough 지원 여부
  • 구매하려는 그래픽 카드의 Multi-OS Enable 여부
  • 사용중인 어플리케이션의 CPU 요구 사항 (일반적으로 1개의 VM에 적어도 1개의 vCPU를 할당해야 할 수 있다)
  • 사용중인 어플리케이션의 Disk I/O 요구사항
  • Infini Band 또는 10G 네트워크
  • 작업 결과물을 저장 할 수 있는 스토리지 요구사항 (사이징, 안전성 기타. )

현재까지로서는, GPU에 대한 Passthrough 를 지원하는 하이퍼바이저는 Xen 밖에 없어보인다.(맥에서 사용하는 패러랠즈도 지원 하는거 같기는 하다.) 하지만 이런 인프라의 구성은 사용중인 어플리케이션에대한 전문가 및 인프라 전문가, 그리고 CUDA 환경에 대해 높은 이해를 가지고 있는 여러 분야 사람들의 협업이 필요할 것이다. "HPC 클라우드 구성용 CD한장 원큐 패키지" 와 같은 오픈소스의 일반 모델로 자리잡아 일반인이 리눅스 깔아보듯이 접근하려면 많은 시간이 필요할 것이다. 이런 부분이 오픈소스의 특징이기도 하지만, 구성하는데 필요한 모든 재료는 이미 주어졌다.

HPC 클라우드는, IaaS 클라우드 서비스의 많은 형태 중 단 한가지 일 뿐이다. 국내에서 이 단계로까지의 서비스를 제공하려는 사업자가 있을지는 모르겠지만, 이는 분명 어디엔가는 필요한 인프라일 것이며, 고객에게 Private HPC 클라우드로서 Farm을 제공하는 형태의 서비스가 가능하다면, 아마도 기존의 많은 연구기관들을 유치 할 수 있지 않을까 하는 생각을 해 본다.


부연적으로 한가지 더 말하자면, 이는 이 글을 쓴 이유이기도 한데, 이러한 접근이 쉬운 환경이 대학생이나 연구원들에게 공개적으로 열리게 되면 아무래도 기존보다는 훨씬 더 좋은 연구 인프라의 확보가 가능하지 않을까 생각해 본다. 사업 하고 싶어도 서버 살 돈이 없었던 사람들에게 컴퓨팅 클라우드가 유용했던 것처럼, 이러한 HPC 클라우드는 많은 기초과학 분야, 그리고 이런 과학을 공부했던 학도들이 나중에 연구소에 뛰어들게 되었을 때, 보다 경쟁력 있는 제품을 만들어 낼 수 있는, 장기적인 기반이 되지 않을까 생각해 본다. 기술이 보다 많은 사람에게 저렴한 가격으로 열려있을 때, 이러한 환경을 바탕으로 발생된 새로운 기술로 인해 모든 사람이 더 잘 살수 있는, 또 누군가에게는 성공의 열쇠가 되는 기회가 제공 될 수 있지 않을까.

Nella Fantasia

Image from: http://postfiles7.naver.net/20100727_102/sweetgirl28_1280227194717lvcaW_gif/%EB%AA%85%EA%B3%A1_%EB%84%AC%EB%9D%BC%ED%8C%90%ED%83%80%EC%A7%80%EC%95%84_nella_fantasia__sweetgirl28.gif?type=w2


PCI Passthrough 에 대한 내용
http://www.ibm.com/developerworks/linux/library/l-pci-passthrough/

Citrix 5.6 Multi-GPU Passthrough feature
http://support.citrix.com/article/CTX125574

NCSA Tesla Linux Cluster
http://www.ncsa.illinois.edu/UserInfo/Resources/Hardware/Intel64TeslaCluster/

TESLA
http://www.nvidia.com/object/preconfigured-clusters.html

클러스터를 사용한 수퍼컴퓨팅 디자인 - 뉴 멕시코 컴퓨팅 센터
http://nmcac.net/encanto.html

쿵푸팬더와 HPC, PDF 문서
http://science.energy.gov/~/media/ascr/pdf/benefits/Hpc_dreamworks_072809_a.pdf

렌더팜을 만드는 방법, Tom's Hardware
http://www.tomshardware.com/reviews/render-farm-node,2340.html

Amazon HPC Cloud & Case Study
http://aws.amazon.com/ec2/hpc-applications/
NASA JPL(Jet Propulsion Lab)
http://aws.amazon.com/solutions/case-studies/nasa-jpl/
Harvard Medical School
http://aws.amazon.com/solutions/case-studies/harvard/





( younjin.jeong@gmail.com, 정윤진)

Cloud Build? Build in Cloud?

Techs
( younjin.jeong@gmail.com, 정윤진 )


이제는 대세라 부르기도 뭣하다.  작년 KT가 야심차게 기업의 사활을 걸었다며 아마존 클라우드 서비스와 같은 IaaS 를 목표로 뜀박질 하기 이전까지만 해도 국내에서의 클라우드는 그게 뭥미?  또는 그거 지금 필요 없삼 의 반응이 지배적이었다.

하지만 KT로 부터 촉발된 클라우드 사업 경쟁의 시작은, 올해 초부터 호스트웨이의 Flex Cloud 서비스를 필두로 SK 의 T Cloud, LG CNS Cloud 등 수많은 클라우드 플랫폼들이 등장하면서 바야흐로 춘추전국시대를 앞두고 있다.  하지만 2011년 중반 현재까지, 아마존의 클라우드에 필적할 만한 인프라스트럭쳐 클라우드는 국내에는 없어 보이며, 만약 아마존이 국내 시장에 등장한다면 ( 그럴일은 별로 없지만 ) 아마 다른 모든 클라우드들은 초라해 지지 않을까 생각한다. 


예전의 클라우드사마


이제는 아무도 이런 블로그에서 클라우드 하면 이 파이널 판타지 7의 클라우드를 떠올리지 않는다. 

클라우드란건, 궁극적으로 서비스를 만들어서 제공해야 하는 입장에서는, 즉 아마존과 같은 클라우드를 서비스 하겠다 하고 퍼블릭 클라우드 사업에 뛰어들 기 위해서는 기술적으로 심각하게 고려되어야 하는 것들이 몇가지 있다.
요즈음 옥션의 광고에서 처럼, 당신이 고객이 되어 본다면 이러한 IaaS 클라우드 서비스에서 고객의 입장으로 클라우드를 사용할 때 고려할 것들은 다음과 같다.

  • 인스턴스의 생성/삭제가 허용할 만한 범위내의 시간에서 이루어지는가.
  • 내가 원하는 경우 어떠한 형태로든 인스턴스의 데이터에 대한 백업이 가능한가.
  • 내 인스턴스를 우리 서비스에 맞는 어플리케이션을 설정하고, 이를 템플릿화 하여 재사용이 가능한가.
  • 내가 사용한 트래픽/프로세싱파워/스토리지 공간 등에 대한 과금이 정확하며 합리적인 것인가.

이는, 내가 매번 내부 교육이나 PT에서 강조하는 클라우드의 가장 큰 특성인 "신축성"에 더하여, 퍼블릭 클라우드가 가져야 하는 최소한의 성능 및 요구조건을 이야기 한다.  위의 넷중 하나라도 제대로 동작하지 않는다면, 클라우드는 클라우드로서의 경제성/기능성을 잃게 되고, 고객은 떠날 것이다.

이러한 요구 조건들을 당최 어떻게 충족시킬 것인가? 
다시 클라우드를 만드는 사람의 입장에서,

  • 고객 인스턴스의 충분한 사용성을 확보하기 위해서, 다음의 리소스에 대해 수많은 테스트와 적절한 플랫폼/아키텍쳐에 대한 고민이 필요하다.
  • 스토리지 I/O 성능
  • 네트워크 구조 및 구간별 대역폭
  • 전체 시스템 내에서 고객 인스턴스들의 오케스트레이션
  • 클러스터 노드들의 스펙
  • 보다 쉬운 개발 및 관리를 위한 자동화 방법/구조 선택
  • 효율적인 모니터링 시스템의 구현
  • 사용자 계정별 적절하고도 비교적 정확한 과금방법 구현 
  • 경쟁사 대비 보다 저렴한 구축비용 
  • 고객 사용성과 서비스 제공에 대한 적절한 Trade off

위의 몇가지에서 파생될 수 있는 수많은 가능성은 굳이 언급하지 않아도 골치 아파질 것이다.  이렇게 고려해야 할 것들이 많을진데, 우리나라 클라우드들은 조금 써보면 궁금해 지는 부분이 없지 않아 있다.  아직 상용화 하기엔 이른 부분들이 있어 보이고, 경쟁사를 인식해 너무 서두르는 감이 있지 않나 싶다.

클라우드는, 내부에서 실험적으로 사용하고자 할때 비용과 자원만 있다면 반나절만에도 구축 가능한 플랫폼이다.  하지만 이런 클라우드를 "고객이 사용해 보고 만족할 만한" 플랫폼으로 만드는 것은 수많은 전문 인력들이 수개월 동안 애자일과 같은 모든것이 공유되고 모든 코드가 내부에 공개된 고도의 협동조직이 만드는 것이 아니면 안된다.  전문화된 스토리지 엔지니어와 서버개발자, 백엔드와 프론트 엔드 개발자, 가상화 전문가 등 각 분야에 매우 전문적인 서로다른 인력들이 팀으로 조화되지 않는다면 사실 클라우드 만들기는 돈지랄 하는 소꿉장난이 될 수 밖에 없을 것이다.

우리나라의 기업 및 IT 조직 구조는 사실 이런 형태가 아닌  시스템 하는 사람 모임 시스템 팀, 개발해서 기능 추가하는 사람들의 모임 개발팀, 데이터베이스 관리하는 DBA팀 과 같이 같은 직무를 수행하는 사람들로 이루어 진 경우가 많이 있다.  이러한 구조는 기존의 구조를 "유지" 하는데는 좋을지 몰라도, 클라우드와 같은 "대주제" 를 소화하기에는 이미 너무 구시대적이며, 맞지 않는다.  조직은 기본적으로 다른 조직과 경쟁 할 수 밖에 없는데, 이러한 조직의 형태는 이미 경쟁이 될 수가 없다.  경쟁이 되지 않는데 경쟁을 붙여 놓으면 ( 고가평가) 당연히 싸움이 나고 프로젝트는 산으로 간다.

뭐, 조직내로 숨고 싶어하는 사람들이 많은 국내의 많은 직장인들은 사실 내가 노출되어 능력을 발휘해야 하는 포지션이 되는것이 두려운 분들이 많다는 것도 잘 알고 있다.  이런 분들은 나중에 OP 교육해서 원래 하던대로 하시도록 하고, 그런 성향이 아니며 충분히 능력이 있는 분들을 플랫폼 개발 일선으로 배합해야 하는 것도 매우 중요한 과제 되겠다. 글고 울나라는 아이비 리그 같은 좋은 학교 졸업하신 분들이 ( 꼭 언급된 특정 대학을 비난하고자 하는 의도는 없음 ) 이런 일 잘 할것으로 기대하는데, 사실 꼭 그렇지만은 않다.  이런 분들은 대개 더 높은 곳을 바라 볼 수밖에 없고, 비용이 굉장히 높을 수 밖에 없다.  뭐 그렇다 할 지라도 잘 만들어 주면 좋은데, 이게 또 그렇지 않은 경우가 대부분이랄까.  사실 이런 하이스펙의 인력으로 TF 를 채우는것은 상부로의 보고를 쉽게 만들고 프로젝트 실패를 "원래 할 수 없었던 것" 으로 만들기 위한 회피기동의 최우선 과제 일 뿐이다.  물론 다른 이유들이 더 있겠지만,  이런 부분들이 클라우드 완성을 위한 필요 요소가 되지 않음은 당연지사 일 것이다.

정리하면, 클라우드를 만드는 것은 매우 비용이 많이 들고, 인력의 관리 및 확보가 쉽지 않으며 경험있는 사람이 많지 않기 때문에 이 사람들에게 실패를 통해 기술을 축적할 시간을 주어야 하고, 이를 통한 대다수의 관리자들에가 충분한 교육이 될 수 있도록 하지 않으면 안될 것이다.  이런 과업을 수행하기 위해서 조직의 구조와 문화가 변경되어야 하고, 기존의 조직과는 분리가 되어야 하며, 그 인원의 충원에 있어서도 이전과는 다른 기준을 적용해야 한다.  이런 모든 것들 때문에 클라우드의 실현이 쉽지만은 않은 것이라 생각한다.




예전 Cloud Connect Event 에 갔을때 어떤 사람이 이런말을 했다. 

"자동차가 처음 나왔을때, 많은 사람들은 자동차가 순식간에 말과 마차를 대체할 것이라고 생각했습니다.  하지만 당시의 사람들은 그저, 보다 조금 빠른 말과 마차를 원했을 뿐 입니다."

또는, 만약 전쟁사를 좋아한다면 베트남 전쟁시 미군이 최신무기인 미사일에 대한 무한 신뢰로 팬텀 전투기에서 기관포를 아예 제거해 버림으로서 조종사들에게 원성을 샀던 일화를 알고 있을 것이다.

이제, 클라우드를 이용하는 고객의 관점에서 생각해 보자. 클라우드는 이제 시작되었고 ( 물론 실리콘벨리에서는 5년 전 즈음에 시작되었다. )  이 클라우드에 대한 이론적 사업모델과 실제 아마존/랙스페이스/고그리드 같은 기업들도 생겨났다.  또는 우리는 클라우드에요 라고 말하고 있지는 않지만 그 서비스 구성의 알려진 일부 모델이 클라우드 또는 어플리케이션 클러스터의 형태를 띄는 구글의 서비스, 또 막대한 데이터 양을 처리하는 Flickr 나 Twitter, Facebook 과 같은 서비스 모델들도 생겨났다.  이들은 모두 일종의 선구자들이고, 자동차 산업의 벤츠, 포르쉐, 페라리와 같은 존재들이다.  그들은 그와 같은 모델을 만들기 위해서 어떠한 부분에 가장 많은 자원을 투자했는지 조차 비밀에 부치며 그들의 경쟁력을 유지하고 있다.

 


하지만 그러한 비밀의 핵심 내용은 사실 간단하다.  현대의 웹 어플리케이션은 많은 부분에서 예전의 도스시절 C로 작성한 어플리케이션 보다 어플리케이션 자체로서의 비밀의 비중이 낮다.  이말은 쉽게 말하면 도스시절보다 현대의 웹세상이 프로그램 만들기가 보다 쉽다는 말이다. 여기에 전제를 달아야 하는것이 바로 '기능 구현 면에서는' 이 될 것이다.  그런데 도스 시절보다 어려워진 것이 웹 세상에 있는데, 웹 세상에 있는 사람들은 보통 이런 부분을 많이 생각하지 않는다. 적어도 국내에서는.  그 부분이 바로, '분산을 위한 어플리케이션 구조' 일 것이다.  다른말로 이런 아키텍처링은, 위에서 말한 모든 회사의 비밀의 핵심이다.  이러한 비밀이 풀리는 순간, 아류의 서비스는 순식간에 등장하여 경쟁력을 약화 시킬것이 분명하다.  하지만 아이러니하게도, 국내에서 이런 부분에 관심을 가지는 분들은 각 기업 연구소에 계신분들은 안계신 듯 하다.  사실 큰 관심도 없어 보인다.  그래서 벤처들이 좋은 기회를 맞이하는 부분도 있을 수 있겠지만, 역시 국내의 여러가지 환경에서 이런 부분에 대한 고려를 해 달라 라는것은 현실적으로 무리가 따르는 것도 사실 아닌가.

클라우드란건 이제 페이스북과 같은 서비스를 시작하려는 불특정다수의 사업가들과 또 이러한 사업가들에게 네트워크 대역폭과 컴퓨팅/스토리지를 판매하려는 일종의 기간사업가 양측 모두에게 매우 매력적인 플랫폼이라 인식되고 있다.
하지만, 난 이런 이야기를 하고 싶다.  서비스의 단위리소스, 즉 웹서버라던가 디비서버, 스토리지 등을 1로 만드는건 그 개발기간이 2로 만드는 것보다 짧고 쉽다.  2로 만드는것은 1로 만드는 것보다는 어렵지만, 3으로 만드는 것 보다는 쉽다.  하지만, 진정한 클라우드의 마법은 3으로 만들었을때 시작되며, 3으로 만들 수 있도록 고려된 서비스는 n 으로 확장 가능할 것이다.  이러한 기술적 또는 클라우드의 특성에 대한 고민 없이 클라우드에 기존 서비스를 그저 "올려" 만 놓는 형태의 클라우드 사용은, 페이스북을 꿈꾸는 당신의 사장님에게 좌절을 안겨다 줄 뿐이다.

뭔가 주제없는듯 글만 길어지는 듯 한데,  클라우드를 만들려고 하는 사람이던, 클라우드를 사용하려고 하는 사람이던 클라우드는 사람과 조직에게 그에대한 경험을 익힐 시간을 필요로 할 것이다.  이러한 시간에 충분히 마이그레이션, 어플리케이션의 구조에 대해 고민하지 않는다면, 클라우드의 사용은 오히려 당신의 조직에 관리하기 어려운 비용만 많이 나가는, 골칫덩이 시스템이 될 것임을 보장한다.

그리고 여담이지만, 기술 매니저가 반드시 그 조직 내에서 정리를 해야 할 사람이 있다면, 그건 클라우드와 가상화 이야기를 듣자마자 그 플랫폼에 오라클 RAC 를 구성하자고 떠드는 사람일 것이다.


 
세상은 브라우저를 중심으로 빠르게 발전하고 있다.  클라우드만큼 중요시 보아야 할 것들이 바로 모든 플랫폼에서 동작하는 브라우저의 발달이다.  결국 클라우드 - 브라우저 발달은 서로 불가분의 관계로 결합되어 있어,  웹의 어떠한 형태가 다수의 플랫폼에서 접근하는 서비스성이 있는 수많은 고객들이 브라우저의 형태로서 제품을 체험하게 될 것이고, 이러한 웹의 형태에 대해 이해를 하고 클라우드에 대해 이해를 하여 이 맞물리는 접점에 대한 설계에 대한 고민을 할 줄 아는 사람들이 모여야만 수많은 그야말로 수억의 데이터를 처리 할 수 있는 모델이 나타나게 될 것이다.  사실, 사업하는데 처음부터 이런 기술적 고려를 할 필요는 없다.  사업성과 고객유치가 우선이며, 이러한 것들이 충족되고 기획단계에서 이런 확장성에 대한 고려를 마일스톤에 넣기만 한다면 문제 될 것은 많지가 않다.  다만 내가 말하는건, 개념없이 요새같은 세상에 오라클 웹로직 때려박을 생각은 좀 자중하고, asp 코딩하는것도 좀 참아 주길 바랄 뿐이며, 웹에 종사하는 사람이면 적어도 CDN 과 NoSQL, Reddit 같은 것들만 조금 고려해 주면 된다는 말이다.

삼천포로 빠졌는데,  브라우저는 역시 중요하다.  그리고 각 플랫폼 별 공통으로 동작 가능한 어떠한 형태의 코드나 프레임웍들도 중요하다.  이런 기술들이 클라우드와 연계되는 것도 중요하다.  당신이 Comet 으로 설계된 백그라운드 트랜젝션 로직을 RESTful 하게 구현했으면, Jetty 같은 웹 서버를 클라우드에서 어떻게 돌려줄 것인가 하는것도 고민해야 한다는 말이다.  그렇기 때문에 서로다른 직군이 클라우드를 만드는 사람들 처럼 클라우드에서 돌릴 서비스를 만드는 사람들에게도 중요하게 되는 것이다.


글재주가 많이 없어져서, 전체 글을 관통하는 주제를 통일성있게 설명할 능력도 없는것 같다.  굳이 말하자면, 클라우드라는것은 모두에게 중요하고, 클라우드에서 돌릴만한 대용량 서비스를 만드는 부분이나 클라우드를 만드는 부분이나 이제는 새로운 형태의 협업을 요구하고 있다.  이러한 협업과 기술에 대한 이해없이는, 국내에서는 절대로 Amazon / Facebook 서비스가 나타 날 수 없을 것이다.  아류는 판 칠 수 있을지라도.


클라우드는 기업 경제/기술/문화 등 많은 측면에서 다룰만한 주제가 많은 핫 아이템이다.  모두 다 다룰 수는 없는 일이고, 그럴만한 글재주도 되지 않지만,  그 구현의 방법처럼 많은,  말 그대로 '구름처럼 많은' 무엇을 만들기 위해 또 그런 양의 데이터가 움직이는 세상에서 당신이 뭘 해야 할지는 생각해 볼 필요가 있지 않나, 싶다.


몰래_똥싸는_IT인.jpg



( younjin.jeong@gmail.com , 정윤진 )