'azure'에 해당되는 글 109건

  1. 2014.09.15 ubuntu 14.04에서 asp.net vnext 설치하고 사용하기, mono 3.8 업데이트
  2. 2014.07.07 Azure VHD 디스크 생성 시 캐시 지정에 관하여
  3. 2013.10.20 Windows Azure Linux Virtual Machine과 docker를 이용한 Linux 기반의 C# 개발 환경 구축
  4. 2013.10.13 ZIP 파일을 이용한 Windows Azure Storage의 저장 공간 효율 극대화하기
  5. 2013.10.12 ASP.NET을 이용한 이식성 높은 클라우드 서비스 개발하기
  6. 2013.10.05 SendGrid E-MAIL 서비스로 E-MAIL 보내기
  7. 2013.03.31 Windows Azure를 통한 클라우드 서비스 확장성 포스터
  8. 2013.03.07 Cloud Service 레시피 - Windows Azure Cloud Service 프로젝트 안에서 실행 환경을 구분하는 방법
  9. 2013.02.26 Windows Azure Worker Role에 여러 진입점 클래스가 있는 경우
  10. 2013.02.03 Azure BLOB 저장소 레시피 - 모바일 홈페이지 만들기
  11. 2013.02.03 Azure 가상 컴퓨터 레시피 - 지역 설정 업데이트하기
  12. 2013.02.01 Windows Azure 사용 후기도 올리고 경품도 가져가세요!
  13. 2012.12.06 Azure Camp @ 인하대 - 리눅스, Windows Azure를 만나다
  14. 2012.12.03 Windows Azure Virtual Machine에 Apache 2 + PHP 5 + Cubrid + XE 설치하기
  15. 2012.11.01 2012년 11월 Windows Azure 관련 소식 종합
  16. 2012.09.15 Visual Studio 2012 Express 출시 (1)
  17. 2012.08.06 클라우드 시대의 피아식별: Access Control #3
  18. 2012.08.02 Windows Azure 관리자 포탈 사이트에 대하여
  19. 2012.07.13 Windows Azure Media Service 활용하기
  20. 2012.05.31 Windows Azure 매거진을 시작합니다.
  21. 2012.05.25 CentOS, Fedora, RHEL에서 SQL Azure 접속하기
  22. 2012.05.14 VM Role 생성을 위한 가상 하드 디스크 템플릿 파일
  23. 2012.04.17 ASP.NET Universal Provider 소개
  24. 2012.03.28 Microsoft MVP 지식 나눔 강연 (2012년 3월 29일)
  25. 2012.01.05 Windows Azure의 리눅스 지원 추가
  26. 2011.12.15 AppFabric 브랜드 네임의 전면적인 수정
  27. 2011.09.27 Windows Azure Storage 2011-09 Update 소개
  28. 2011.09.12 ASP.NET과 IIS 7을 위한 로드 밸런싱 전략과 기초적인 이야기, 그리고 Azure Platform
  29. 2011.09.02 Windows Azure Cafe Boot Camp #3
  30. 2011.08.09 앱 세상을 준비하는 APPCAMP 2011년 8월
PaaS2014. 9. 15. 09:38

NOTE: 지난 번에 올렸던 글 이후로 mono 3.8이 빠르게 추석 연휴를 사이로 업데이트가 되었는데, mono의 최신 버전을 설치하는 과정이 무척 복잡하고 까다로웠던 점이었던게 상당히 아쉬웠습니다. 그런데 이 부분이 잘 해결된 듯 하여 업데이트된 내용을 더해 글을 더 보강하여 다시 게시합니다.

 

 

다시 말씀드리면, 이 블로그 포스트는 MS Azure Virtual Machine과 Ubuntu Server 14.04 버전을 최초 설치했을 때의 상태를 기준으로 작성된 것이며, 이 블로그 글을 작성하는 2014년 9월 현재 ASP.NET vNext가 정식 출시 전임을 말씀드립니다.

주의: 실제 배포 환경에서 이 블로그 포스트의 내용을 활용하시는 것은 매우 위험합니다.

사전 준비 작업

중요: 이 아티클에서 소개하는 내용은 Ubuntu 14.04에서 작동하며, Ubuntu 12 버전에서는 패키지 버전 불일치 등으로 인하여 mono 3.8이 정상적으로 설치가 되지 않아 실행할 수 없습니다.

최근들어 변경된 사항으로, Mono의 최신 버전 릴리즈는 Xamarin이 독자적으로 운영하는 패키지 리포지터리를 통하여 좀 더 빠르게 받아보실 수 있습니다. 하지만 2014년 9월 현재 모든 배포판에 대해 완전하게 설치를 보장하는 것이 아닌 것으로 보입니다.

Mono 3.8 및 그 이후 버전을 설치하기 위하여 우선 해야 할 일은 Xamarin 리포지터리를 시스템에 추가하는 일입니다.

단순한 설명을 위하여, 현재 로그인한 사용자의 홈 디렉터리로 일단 디렉터리 변경을 하겠습니다.


cd ~

Xamarin 리포지터리의 GPG Key를 내려받도록 합니다.


wget http://download.mono-project.com/repo/xamarin.gpg

그리고 내려받은 GPG 키를 저장합니다.


sudo apt-key add xamarin.gpg

/etc/apt/sources.list 파일을 편리한 텍스트 편집기로 열고, 가장 마지막에 다음의 줄을 추가한 후 저장하고 닫습니다.


deb http://origin-download.mono-project.com/repo/debian/ wheezy main

패키지 캐시를 업데이트하기 위하여 아래 명령어를 실행합니다.


sudo apt-get update

이제 Mono 3.8을 설치할 준비가 다 되었습니다. 아래 명령어만 실행하면 됩니다.


sudo apt-get -y install mono-complete

설치가 다 끝나면 mono의 버전을 확인해봅니다.


mono –version

K Runtime과 ASP.NET vNext 설치하기

Mono 3.8이 9월에 릴리즈하고 나서 K Runtime과 ASP.NET vNext를 테스트하는 방법에도 조금 변화가 생겨서 그 내용을 같이 말씀드립니다.

HTTPS/SSL 인증서들을 추가하고 Mono에서 사용할 수 있도록 동기화하는 작업을 반드시 실행합니다.


sudo certmgr -ssl -m https://go.microsoft.com
 sudo certmgr -ssl -m https://nugetgallery.blob.core.windows.net
 sudo certmgr -ssl -m https://nuget.org
 sudo certmgr -ssl -m https://myget.org
 mozroots –import –sync

ASP.NET vNext를 실행하기 위해서는 unzip 패키지가 필요합니다.


sudo apt-get install unzip

그리고 ASP.NET vNext 설치 스크립트를 내려 받습니다.


curl https://raw.githubusercontent.com/aspnet/Home/master/kvminstall.sh | sh && source ~/.kre/kvm/kvm.sh

source 명령을 사용하여 K runtime을 쉽게 실행할 수 있도록 설정합니다.


source ~/.kre/kvm/kvm.sh

2014년 9월 23일 현재 최신 버전은 1.0.0-alpha4-10353입니다. 이 버전을 내려 받기 위하여 KRE_FEED 환경 변수에 Feed URL을 설정하고 해당 버전을 설치합니다.


export KRE_FEED=https://www.myget.org/F/aspnetvnext/api/v2
 kvm install 1.0.0-alpha4-10353

예제 소스 받아서 테스트해보기

이전 아티클에서 이야기했던 내용을 좀 더 보강하면, 현재 ASP.NET vNext의 k web 명령은 아직 Windows 환경에서만 실행이 가능한 상태입니다. Mono를 통하여 웹 서버를 시작하고 ASP.NET vNext를 호스팅할 수 있게 하려면 project.json에 별도의 명령어를 추가해주어야 합니다. 물론 이는 추후에 정식 버전이 릴리즈가 될 때 당연히 해결될 문제이므로 걱정하지 않으셔도 됩니다.

git 패키지를 설치하도록 합니다.


sudo apt-get install git

ASP.NET vNext Home 리포지터리에서 예제 소스를 체크아웃합니다.


git clone https://github.com/aspnet/Home.git

늘 그렇듯이, 콘솔 프로젝트를 시작점으로 잡아봅니다. :-)


cd ~/Home/samples/ConsoleApp/
 kpm restore
 k run

그리고 현재 알파 버전의 ASP.NET vNext 기준으로 리눅스에서 웹 서비스를 실행해보기 위해서는 NOWIN 팩토리 패키지를 구성해야 할 필요가 있습니다.


cd ~/Home/samples/
 mkdir Nowin.vNext
 cd Nowin.vNext
 wget https://github.com/davidfowl/HelloWorldVNext/raw/master/src/Nowin.vNext/NowinServerFactory.cs
 wget https://github.com/davidfowl/HelloWorldVNext/raw/master/src/Nowin.vNext/project.json

위와 같이 준비되면, HelloWeb 프로젝트의 project.json에 들어있는 dependencies 섹션과 commands 섹션을 편집기로 조금 수정하여 앞서 만든 NOWIN 팩토리로 서버를 띄울 수 있게 해야 합니다. project.json에 대한 자세한 내용은 Project.json 파일 을 참고하십시오.


cd ~/Home/samples/HelloWeb/

project.json 파일을 편집기로 열고 각각 다음의 사항을 반영하도록 합니다.
•dependencies에 다음을 추가합니다.
“Nowin.vNext”: “”,
•commands에 다음을 추가합니다.
“nowin”: “Microsoft.AspNet.Hosting –server Nowin.vNext”,

project.json 파일을 저장하고, 다음의 명령어를 실행합니다.


kpm restore
 k nowin

앞에서 다운로드 한 Nowin Factory 프로젝트의 코드를 보면 TCP/5000 포트를 웹 리스너 포트로 사용하고 있습니다. 밖에서 호스트 이름과 함께 5000번 포트로 접속하면 웹 페이지가 나타나는 것을 볼 수 있습니다. 그리고 서버를 종료하려면 콘솔에서 아무 키나 누르면 종료가 됩니다.

만약에 원격에서 좀 더 지속적으로 서버의 성능을 측정해보고 싶으시다면 screen 유틸리티를 사용하여 세션을 분리하신 상태에서 위의 명령어를 입력하고, 서버가 떠 있을 때 Ctrl 키를 누른 상태에서 빠르게 a, a, d 키를 누르면 세션이 분리되어 계속 살아있는 서버가 만들어집니다. 이 상태에서 Apache Bench (AB)등의 유틸리티를 사용하여 부하 테스트 등을 해보시는 것도 의미가 있을 것입니다.

참고로, NAT 환경이나 퍼블릭 클라우드 환경에서는 대표 IP 주소에 대한 외부 방화벽 설정을 열어주셔야 밖에서도 접속이 가능합니다.

마무리

ASP.NET vNext는 계속 업데이트가 이루어지고 있는 상태이며, Mono 런타임의 개선에 따라 리눅스와 맥 OS X에서 ASP.NET vNext를 사용하는 것이 좀 더 쉬워지고 간편해질 전망입니다. 더 많은 기대를 해도 좋지 않을까 생각합니다. :-)

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

IaaS2014. 7. 7. 09:30

Microsoft Azure에서 실행되는 VM은 Azure BLOB Storage를 사용하여 VHD 디스크를 동적으로 연결하여 사용합니다. 이것은 광의로 해석하면 Storage Area Network 위에서 실시간으로 호스팅되는 가상 디스크를 마운트하여 사용하는 셈인데, 실제로 Microsoft Azure의 VM이 시험판 단계일 때에는 예기치 않은 문제들이 제법 많았습니다. (물론 지금은 그런 일도 없고, 또 그렇게 되어서는 안되겠죠.)

 

 

Azure BLOB Storage 그 자체도 내부적으로 상당히 많은 추상화가 이루어져있는 복잡한 기술이지만, 이것을 기반으로 하는 VHD를 사용한다는 것은 어떻게 생각하면 추상화의 극을 달린다는 느낌에 가깝습니다. 물론, 이토록 고도화된 시스템을 사용하기 때문에 얻을 수 있는 이점으로는 무중단 상태에서 같은 지역은 물론 여러 지역에 걸쳐 VHD를 실시간으로 미러링하여 백업하거나 VHD 자체를 로드밸런싱하는 등의, 종전의 클라우드 서비스 공급자들도 상상하기 어려운 스케일의 서비스를 제공할 수 있게 된 점은 있습니다. 하지만 흔히 기대하는 베어메탈급의 고성능 서버와는 거리가 멀리 떨어진 듯한 느낌을 지울 수는 없겠지요.

엄밀히 말해서, 정말 빠른 디스크 I/O를 필요로 한다면 오히려 클라우드 환경에 의존하기 보다는 직접 고성능 서버를 구입하여 구축하는 것이 훨씬 더 이치에 맞습니다. 하지만, 단순히 디스크 I/O가 빨라야 하는 요구 사항을 고려하는 것이 아니라면, 대부분의 인프라의 가치는 장애 대비와 적시 복구인 경우가 많습니다. 이런 점을 고려하여, 어느정도 만족할만한 수준의 디스크 성능과 안정성을 동시에 거둘 수 있는 간단한 팁을 하나 올립니다.

Azure에서 VM을 만들고 디스크를 추가로 생성하여 연결할 때, 다음 그림과 같이 질문을 받습니다.

001

여기서 제일 아래쪽의 호스트 캐시 기본 설정이라는 항목이 제가 오늘 말씀드리려는 내용에 대한 것입니다.

호스트 캐시란 앞에서 이야기한 대로 실제 디스크 I/O를 처리하기 위한 과정에서 중간에 관여하는 구성 요소로, 원칙대로라고 한다면 Azure Storage의 VHD에 대해 발생하는 디스크 I/O를 Azure Storage가 완전히 처리해서 응답을 되돌려주기까지의 과정을 운영 체제의 입장에서는 기다려야 하는 셈입니다. (물론 여기서 다 설명하기에는 어려울 정도로 복잡한 메카니즘이 있어서 정말 순진하게 캐시를 사용하지 않는다고해서 무작정 기다리기만 하는 것은 아닙니다.)

그러나 좀 더 적극적으로 개입해서, 실제로 디스크 I/O가 저멀리 있는 Azure Storage에 전달이 되기 이전이라고 하더라도, 확실하게 디스크 I/O에 대한 요청이 접수되었고 처리가 되었음을 기억하여 정확한 응답을 되돌려주면서, 다른 한편으로는 그 내용을 실제 Azure Storage의 VHD에 지속적으로 보내주는 역할을 따로 수행하게 됩니다.

다르게 말하면, 만약 Azure Storage와 연결이 끊어지거나 문제가 발생하는 경우 캐시의 유효성이나 지속성에 문제가 생겨서 서비스 장애로 이어지는 불상사가 벌어질 수 있습니다. 그러나 바꾸어 말하면 캐시를 사용하지 않을 때에는 이것이 직접적으로 VM 위에서 돌아가는 프로그램에 대한 OS의 IO API 호출에 대한 실패로 직격탄이 되어버립니다. 이런 점을 고려해보면, 문제의 전파나 영향 범위를 최소화하는 관점에서 캐시가 미미하지만 어느정도 역할을 수행하는 것도 가능합니다.

이러한 성격의 캐시를 사용할 수 있는 방안은 두 가지가 있는데, 읽기 작업을 위한 캐시만 사용하는 경우와, 읽기/쓰기 작업을 모두 관리하는 캐시를 사용하는 경우입니다. 운영 체제용으로 만들어지는 VHD는 읽기/쓰기 작업을 모두 관리하는 캐시를 기본으로 사용하도록 하고 있습니다. 그리고 추가 연결하는 디스크에 대해서는 디스크 I/O 빈도가 높지 않을 것임을 가정하고 기본적으로는 캐시 없이 직접 Azure BLOB Storage와 연결되도록 하는 것이 기본입니다.

이러한 상황에서, 만약 디스크의 읽기 성능이 중요하다면 읽기 캐시를 사용하도록 해주는 것이 필요합니다. 이렇게 하면 최초로 캐시에서 가지고 있지 않은 데이터 영역에 대한 요청이 들어왔을 때, 이를 캐시에 저장하고 다음 회차 요청 때 좀 더 빠르게 전달할 수 있도록 해주는 식이 됩니다. 물론 쓰기나 다른 동작에 의해 변경이 발생하게 되면 이에 맞추어 당연히 캐시도 다시 형성됩니다.

여기에 쓰기 캐시를 사용하는 것 까지 포함하게 되면, 쓰기 캐시에 들어오는 요청과 읽기 캐시의 내용을 병합하여 중간 버퍼를 형성하고 Azure Storage의 VHD와 동기화하는 작업을 적극적으로 개입하여 수행하게 됩니다.

결론을 이야기하면, 쓰기 작업이 많은 응용프로그램을 위해 디스크를 추가할 때는 읽기/쓰기 캐시 사용을, 웹 사이트나 읽기 작업이 많은 응용프로그램을 위해서는 읽기 캐시 사용을 권할 수 있습니다.

사실 클라우드 서비스를 사용한다는 것이 어떤 의미인지 본질적으로 잘 이해하고 계시다면, 그리고 필연적으로 사람이 하는 일에 있을 수 있는 결함성을 인정하신다면, 이러한 아키텍처 속에서 갑작스럽게 나타날 수 있는 예외 상황은 항상 관리해야 할 리스크가 될 수 있습니다.

적절한 설정을 확인하고 검증하는 단계를 통해 더 성공적으로 클라우드 서비스를 현업에 투입할 수 있게 될 것입니다.

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

IaaS2013. 10. 20. 22:30

Windows Azure의 Virtual Machine 서비스는 Windows와 Linux를 Guest OS로 지원하는 전형적인 IaaS 플랫폼입니다. 그리고 Linux는 다양한 오픈 소스 소프트웨어와 결합할 수 있는 매우 이상적인 소프트웨어 개발 환경이기도 합니다.

Linux에서 사용할 수 있는 매력적인 소프트웨어들 중 최근 큰 주목을 받고 있는 프로젝트로 docker 프로젝트가 있는데, 이 프로젝트는 기본적으로 Hypervisor 없이 Linux 실행 환경을 가상화하고 서로 격리된 상태로 실행할 수 있도록 도와주는 Linux Container (LXC)를 조금 더 실용적이고 사용하기 편리하게 만들어주는 컴패니언 소프트웨어로, 이미지를 공유하거나, 이미지로부터 생성하는 컨테이너를 만들기 위해 필요한 명령을 자동으로 등록하거나, 컨테이너를 이미지로 변환하는 등의 작업을 단순화합니다.

docker 프로젝트를 설치하고 사용하는 방법에 대한 가이드는 인터넷 상에 이미 다양한 자료로 게시된 적이 있고, 최근에 열린 NAVER 개발자 행사인 DeVIEW 2013에서도 다루어진 적이 있습니다. (http://www.slideshare.net/modestjude/docker-in-deview-2013)

오늘 살펴보려는 내용은 docker 프로젝트를 Windows Azure Virtual Machine 상에서 설치하고 이용하는 방법과 함께, docker Index에 게시되어있는 최신 버전의 Mono 이미지를 다운로드하고 활용하는 방법을 간단히 살펴보려고 합니다. 지금 소개하는 방법을 통해서 쉽고 빠르게 리눅스 기반의 다중 개발 환경을 손쉽고 빠르게 프로토타이핑할 수 있습니다.

시작하기 전에 - Hypervisor 안에서 또다른 가상 환경을 만드는 것은 불가능하지 않습니까?

docker를 일반적인 PC나 서버 환경이 아닌 곳에서 사용할 때 가장 먼저 드는 의문점이 바로 이것입니다. 기본적으로 Hypervisor 위에서 실행하는 OS는 또 다시 가상 환경을 만들어낼 능력이나 여건이 되지 못합니다. 가능하도록 설정했다고 해도 결국 물리적인 한계에 부딪힐 가능성이 커집니다.

사실, docker는 Hypervisor가 아니기 때문에 Hypervisor 고유의 CPU 기능을 활용하는 일은 거의 없고, 호스트가 되는 리눅스의 커널의 재량에 따라 그 안에서 실행되는 독립적인 프로세스일 뿐입니다. 그러나, 제아무리 docker가 유용하다고 해도, 시스템이나 VM에 할당된 자원의 밀도나 품질을 생각해보았을 때 docker가 실제 처리할 수 있는 작업의 양이 항상 효율적이라고는 할 수 없습니다. 따라서, docker를 사용한 시스템 구축은 전적으로 충분한 시나리오 테스트와 QA를 거쳐야만 함을 염두에 두어야 할 것입니다.

docker로 할 수 있는 일

docker는 단순히 프로세스만을 격리하는 것이 아니라 일정 수준의 가상 환경을 다룹니다. 즉, 자체적으로 이용할 수 있는 파일 시스템, 네트워크 어댑터, 가용 메모리 크기 등이 있고, 상황에 따라 이들 자원의 크기가 동적으로 변화하게 됩니다. 그러나 우리가 일반적으로 사용하는 완전한 Hypervisor와는 다르게 자원을 명시적으로 제한할 수 있는 방법이 2013년 10월 현재 기준으로 특별히 없습니다. 그리고 네트워크는 사설 IP로만 할당되기 때문에, docker가 자체적으로 구성하는 NAT를 이용하여 외부로부터 들어오는 네트워크 요청을 특정 컨테이너 앞으로 도착하도록 연결해주는 것이 꼭 필요합니다.

그럼에도 불구하고, docker는 리눅스 기반의 환경에서 항상 있을 수 있는 파일 시스템, 커널, 잘못된 라이브러리나 패키지 설치로 인한 시스템의 중단으로부터 안전하게 지켜줄 수 있고, 신뢰할 수 있을만한 수준을 제공하면서도, 가볍게 다룰 수 있는 가상 환경을 제공한다는 점에서 큰 주목을 받고 있으며, 심지어 Hypervisor 기반의 실행 환경 위에서 전혀 다른 Linux Guest를 추가 실행할 수 있을만큼 유연합니다.

docker Index (https://index.docker.io/)에 게시된 이미지들을 살펴보면 알겠지만 호스트의 Linux OS와 아무 관련이 없는 busybox 같은 응급 이미지도 존재하고, Ubuntu가 호스트인 시스템에서 CentOS를 컨테이너 OS로도 택하는 것이 가능합니다. 즉, docker 환경에 맞추어 개발된 OS이기만하면 docker와의 상호작용을 전제로 호스트 OS와 완전히 분리된 환경에서 실행이 가능하므로 독립적인 환경 구성이 가능함을 뜻합니다.

docker를 Azure Linux VM 위에 설치하기

docker는 LXC 프로젝트를 기반으로 하기 때문에, 커널 버전에 대한 의존성이 크고, 사용할 수 있는 Host OS의 종류에도 제한이 있습니다. 현 시점에서는 Ubuntu Linux 13.04에서의 실행이 가장 안정적이기 때문에, Windows Azure Virtual Machine 갤러리에서 다음 그림과 같이 Ubuntu Linux 13.04 기반의 VM을 하나 추가해서 시작하셔야 합니다. 만약 Ubuntu Linux 12.04나 12.10 버전을 실행 중인 경우 Secure Shell 터미널 환경을 통하여 원격으로 13.04로 업그레이드하는 명령을 실행할 수도 있지만, libcurse 기반의 UI 실행이 일부 필요하기 때문에 putty 등에서는 정상적으로 보이지 않을 수 있고, 또한 잘못 선택할 경우 VM에 원격 접속이 불가능한 상황이 올 수 있으므로 추천하지 않습니다.

http://manage.windowsazure.com/ 으로 접속하여 새 VM을 갤러리로부터 생성하도록 시작합니다. 아래와 같은 대화 상자가 나타나는지 확인한 후 Ubuntu Linux 13.04를 선택합니다.

 

다음 버튼을 클릭한 다음 기본 VM 설정을 입력합니다.

 

PuttyGen을 이용하여 키 체인을 만들어 업로드하거나, 사용자 암호를 지정하고 다음 버튼을 클릭합니다.

 

클라우드 서비스는 네트워크 연결 및 중재를 위한 기본 단위이자 실행 환경을 정의하는 단위 환경입니다. docker 환경과 연결하려는 클라우드 서비스나 다른 VM이 있을 경우 같이 소속되도록 설정해주시고, 가용성 설정 등을 확인한 다음 다음 버튼을 클릭합니다.

 

기본적으로 SSH 포트가 열려있습니다. 그러나 docker container와의 연결을 허용하고 외부에서 접속을 받아들이려면 Windows Azure의 방화벽 설정도 수정해야 합니다. 외부에서 docker container 서비스로의 접속이 안된다면 이쪽의 방화벽 설정을 꼭 확인하셔야 합니다. 마침 버튼을 클릭하여 VM 생성을 시작합니다.

 

VM의 외부 DNS 주소를 확인하고, putty로 접속을 시작합니다.

 

접속이 완료되었다면 이제부터 명령어 입력을 진행합니다. 설치 가이드의 내용은 http://docs.docker.io/en/latest/installation/ubuntulinux/#ubuntu-raring-13-04-64-bit 에서 발췌하였습니다.

우선 최신 패키지 목록을 가져오기 위하여 다음 명령을 수행합니다. 최신 릴리즈를 사용하여 VM을 만들었다면 별 다른 업데이트는 발생하지 않을 것입니다.

sudo apt-get update

그리고 Ubuntu 13.04 시스템들 중 일부 릴리즈에서 누락되어있을 수 있는 AUFS 파일 시스템에 대한 지원 (LXC 실행을 위해 꼭 필요합니다.)을 추가하기 위하여 아래 명령어를 수행합니다. 참고로 Azure Virtual Machine을 통하여 최신 릴리즈를 사용하도록 VM을 생성했다면 역시 AUFS에 대한 지원이 이미 포함되어있어서 아래 명령어로 시스템에 변화가 발생하지는 않을 것입니다.

sudo apt-get install linux-image-extra-`uname -r`

이제 docker 리포지터리에 접근하여 패키지를 설치할 차례입니다. 우선 키 체인을 다운로드하여 시스템에 등록하여 docker 패키지를 인터넷으로부터 다운로드할 수 있도록 허가합니다.

sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -"

OK라는 메시지를 확인하였으면 이어서 리포지터리 목록에 docker 리포지터리를 추가하기 위하여 다음 명령어를 실행합니다.

sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"

이제 패키지 업데이트를 다시 수행하여 사용 가능한 패키지 목록을 갱신합니다.

sudo apt-get update

출력 중에서 다음과 비슷한 메시지가 들어있는지 확인합니다.

Get:3 http://get.docker.io docker/main amd64 Packages [1,395 B]

이제 패키지 목록을 업데이트하였으므로 lxc-docker 패키지가 사용 가능한 상태가 되었을 것입니다. lxc-docker 패키지를 아래 명령으로 설치합니다.

sudo apt-get install lxc-docker

종속 패키지들을 다수 설치해야 함을 알리는 메시지가 나타나면 y 키를 눌러 진행합니다.

설치가 잘 되었는지 확인해보기 위하여 docker Index 사이트로부터 ubuntu 게스트 OS 이미지를 다운로드해보겠습니다. 아래 명령어를 실행합니다.

sudo docker run -i -t ubuntu /bin/bash

아래와 같이 다운로드 메시지가 나타나고 콘솔이 바뀌는 것을 확인하기 바랍니다.

rkttu@dockertest:~$ sudo docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu' (tag: latest) locally
Pulling repository ubuntu
8dbd9e392a96: Download complete
b750fe79269d: Download complete
27cf78414709: Download complete
root@f45ee37cf476:/#

호스트 이름이 Azure VM의 dockertest가 아니라 임의로 작명한 f45ee37cf476이라는 이름으로 바뀐 것을 볼 수 있습니다. 그리고 IP 주소 대역도 다르다는 것을 쉽게 파악할 수 있는데, ifconfig을 비롯한 네트워킹 도구가 이 버전의 이미지에는 들어있지 않기 때문에 다음 명령어를 실행하여 net-tools 패키지를 설치합니다.

apt-get install net-tools

격리 환경 상에서 자동으로 root 권한을 얻었으므로 sudo를 덧붙일 필요가 없습니다. 설치가 끝난 다음, ifconfig eth0 명령을 실행하면 다음과 같이 나타납니다.

eth0      Link encap:Ethernet  HWaddr fa:b2:4f:b9:15:84
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::f8b2:4fff:feb9:1584/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:192 errors:0 dropped:0 overruns:0 frame:0
          TX packets:81 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:267507 (267.5 KB)  TX bytes:5591 (5.5 KB)

굵게 강조 표시한대로 사설 IPv4 주소가 할당되어있습니다. 그리고 패키지 업데이트와 업그레이드를 진행하여 인터넷 연결 상태를 다시 한 번 확인해봅니다.

apt-get update
apt-get upgrade

가상 환경에서 나가기 위하여 exit 명령을 입력하면 다음과 같이 원래의 Host OS로 프롬프트가 바뀌는 것을 볼 수 있습니다.

root@f45ee37cf476:/# exit
exit
rkttu@dockertest:~$

이제 방화벽 설정을 확인합니다. 기본적으로 Ubuntu는 ufw라는 방화벽 프로그램을 이용합니다. 그리고 Windows Azure 기본 구성 이미지에서는 ufw가 비활성화되어있고, Windows Azure의 방화벽이 외부로부터의 연결을 차단하며, Windows Azure 간 네트워크에는 제한이 없습니다. 아래 명령어를 입력하여 방화벽 상태를 확인합니다.

rkttu@dockertest:~$ sudo ufw status
Status: inactive
rkttu@dockertest:~$

그리고 방금 전 테스트를 위하여 받은 이미지와 그 이미지를 기반으로 실행한 컨테이너가 잘 등록되었는지 확인하여 설치 프로세스를 마무리합니다.

rkttu@dockertest:~$ sudo docker images -a
REPOSITORY          TAG                 ID                  CREATED             SIZE
ubuntu              12.04               8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu              latest              8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu              precise             8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu              12.10               b750fe79269d        7 months ago        24.65 kB (virtual 180.1 MB)
ubuntu              quantal             b750fe79269d        7 months ago        24.65 kB (virtual 180.1 MB)
<none>              <none>              27cf78414709        7 months ago        180.1 MB (virtual 180.1 MB)

rkttu@dockertest:~$ sudo docker ps -a
ID                  IMAGE               COMMAND             CREATED             STATUS              PORTS
f45ee37cf476        ubuntu:12.04        /bin/bash           8 minutes ago       Exit 0

예상한 대로 이미지가 다운로드되어있고, 해당 이미지를 기반으로 /bin/bash 앱에 대한 컨테이너가 생성 후 실행되었으며 종료 코드 0으로 종료되었다는 결과 표가 보입니다.

mono 개발 환경 빠르게 구축하기

mono 개발 환경을 입맛에 맞게 구축하는 방법은 여러가지가 있습니다. 방금 전처럼 base image를 받아서 수작업으로 설치하거나, 그 과정을 서술하는 Dockerfile을 만들어 한 번에 일괄 실행하여 시스템의 설치를 전개하는 방식도 있을 수 있습니다. 그렇지만 docker를 개발 환경으로 이용하기 위해서 취할 수 있는 가장 좋은 방법은 docker Index 사이트에 게시된 최신 이미지를 확인하여 해당 이미지를 직접 로컬 시스템으로 Pull 하는 것입니다.

편의를 위하여 잠시 리눅스 콘솔에서 윈도 화면으로 되돌아온 다음 https://index.docker.io/ 로 접속하여 키워드로 mono를 지정하고 검색합니다.

 

 

Ubuntu 이미지를 이용하여 Mono 3.2.3을 설치하여 배포하는 이미지가 Docker Index에 올라와있습니다. 그 외에도, 닷넷 기반의 SOA 실행 및 개발 환경 구축을 편리하게 할 수 있도록 Service Stack과 연계한 리눅스 이미지도 보입니다. 우리가 사용하려는 것은 rwentzel/ubuntu-mono 이미지이므로 이 이미지의 이름을 기록합니다.

이제 다시 리눅스 콘솔로 되돌아가서 해당 이미지를 로컬 리포지터리로 다운로드하겠습니다. 다음 명령어를 실행하여 동기화를 시작합니다. 해당 이미지는 여러 차례 수정을 거쳐 만들어진 것이기 때문에 다운로드에 다소 시간이 걸리니 조금 오래 기다리셔야 합니다.

sudo docker pull rwentzel/ubuntu-mono

이미지 다운로드가 완료되었다면, 이제 이 이미지를 이용하여 컨테이너를 만들고 정말 안에 mono 개발 환경이 들어있는지 확인해볼 차례입니다. 아래 명령어로 이미지를 우선 확인합니다.

sudo docker images -a

설치한 이미지의 갯수가 매우 많아졌습니다. 그런데 주의할 것이 하나 있습니다. docker rmi 명령으로 이미지를 제거하는 것이 가능하지만, 꼭 필요한 경우가 아니라면 가급적 리포지터리나 TAG가 none으로 설정된 이미지를 임의로 삭제하는 일은 피해야 합니다. 콘솔에서는 잘 드러나지 않지만 이미지는 차이점 보관 방식으로 생성되어있고 일종의 트리 계층을 형성하기 때문입니다. 그래서 docker로 이미지를 만들 때 정말 중요하게 관리되어야 하는 이미지는 REPOSITORY나 TAG에 정확한 속성을 지정하여 쉽게 찾을 수 있도록 해주는 것이 중요합니다.

REPOSITORY             TAG                 ID                  CREATED             SIZE
rwentzel/ubuntu-mono   latest              2e8ec476cfd1        3 weeks ago         12.29 kB (virtual 2.627 GB)
<none>                 <none>              866ee2ba174c        3 weeks ago         12.29 kB (virtual 2.627 GB)
<none>                 <none>              9d58fdd1f145        3 weeks ago         28.67 kB (virtual 2.627 GB)
<none>                 <none>              48d313d93277        3 weeks ago         194.1 kB (virtual 2.627 GB)
<none>                 <none>              a6f3f7d033e8        3 weeks ago         1.151 GB (virtual 2.627 GB)
<none>                 <none>              0063533722a2        3 weeks ago         486.2 MB (virtual 1.476 GB)
<none>                 <none>              563cc9ce1df7        3 weeks ago         43.2 MB (virtual 989.9 MB)
<none>                 <none>              d963202bdca8        3 weeks ago         62.24 MB (virtual 946.7 MB)
<none>                 <none>              fa1d9d247e8a        3 weeks ago         27.46 MB (virtual 884.5 MB)
<none>                 <none>              e01eae29dae1        3 weeks ago         32.86 kB (virtual 857 MB)
<none>                 <none>              eb5606044c61        3 weeks ago         70.23 MB (virtual 857 MB)
<none>                 <none>              519b96c9a701        3 weeks ago         29.08 MB (virtual 786.8 MB)
<none>                 <none>              552c68e56d9a        3 weeks ago         46.38 MB (virtual 757.7 MB)
<none>                 <none>              17f3c8064eb6        3 weeks ago         25.59 MB (virtual 711.3 MB)
<none>                 <none>              0cb9cc3fc7b8        3 weeks ago         144.5 MB (virtual 685.7 MB)
<none>                 <none>              898780b65670        3 weeks ago         12.29 kB (virtual 541.2 MB)
<none>                 <none>              de6790a79ec8        3 weeks ago         158.2 MB (virtual 541.2 MB)
<none>                 <none>              29002fa46318        3 weeks ago         24.58 MB (virtual 383 MB)
<none>                 <none>              270acf4d2474        3 weeks ago         96.52 MB (virtual 358.5 MB)
<none>                 <none>              1d4aaea09576        3 weeks ago         81.83 MB (virtual 261.9 MB)
ubuntu                 12.04               8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu                 latest              8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu                 precise             8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu                 12.10               b750fe79269d        7 months ago        24.65 kB (virtual 180.1 MB)
ubuntu                 quantal             b750fe79269d        7 months ago        24.65 kB (virtual 180.1 MB)
<none>                 <none>              27cf78414709        7 months ago        180.1 MB (virtual 180.1 MB)

위의 rwentzel/ubuntu-mono 이미지를 사용하여 내부에 들어있는 /bin/bash를 컨테이너로 실행하기 위하여 아래 명령을 실행합니다.

sudo docker run -i -t rwentzel/ubuntu-mono /bin/bash

그러면 다음과 같이 프롬프트가 변경되는 것을 볼 수 있습니다.

rkttu@dockertest:~$ sudo docker run -i -t rwentzel/ubuntu-mono /bin/bash
root@f739c613d0ae:/#

이제 간단한 C# 소스 코드를 작성하여 프로그램으로 컴파일하고 잘 작동하는지 확인해보겠습니다. vi를 사용해도 좋고, vi 사용에 익숙하지 않은 경우 아래와 같이 명령을 실행하여 pico/nano 에디터를 추가 설치할 수 도 있습니다.

apt-get install nano

Hello.cs 라는 소스 코드를 원하는 에디터로 아래와 같이 작성합니다.

using System;
using System.Linq;
using System.Collections.Generic;

public static class Program {
        [STAThread]
        public static void Main(string[] args) {
                var count = args.Count();
                List<string> options = args.Where(x => x.StartsWith("-")).ToList();
                Console.Out.WriteLine("Hello, World!");
                Console.Out.WriteLine("Total Args: {0}, Option Args: {1}", count, options.Count);
        }
}

Mono 3.2.3은 LINQ와 제네릭을 모두 잘 지원하므로 위의 코드를 아래와 같이 컴파일하였을 때 문제없이 컴파일이 완료될 것입니다.

mcs Hello.cs

그리고 JVM과 마찬가지로 Mono VM을 실행하여 컴파일한 어셈블리 파일을 실행해봅니다.

root@f739c613d0ae:/# mono Hello.exe
Hello, World!
Total Args: 0, Option Args: 0
root@f739c613d0ae:/# mono Hello.exe a b c
Hello, World!
Total Args: 3, Option Args: 0
root@f739c613d0ae:/# mono Hello.exe a b -c
Hello, World!
Total Args: 3, Option Args: 1

의도한 대로 LINQ와 제네릭을 잘 받아서 처리하고 있습니다.

mono 실행 속도 개선하기

최신 버전의 mono는 실행 속도를 개선하기 위하여 가비지 컬렉터를 새롭게 디자인하였고, 전처리 컴파일을 미리 수행하는 방법을 제공합니다. 특히, Microsoft .NET Framework와 마찬가지로 GAC에 대해 ngen을 수행하는 것과 비슷하게 AOT 컴파일을 미리 수행하도록 명령어를 한 번 실행해주면 실행 속도 개선에 큰 도움이 됩니다. 아래 명령어를 실행하여 GAC 내부의 모든 어셈블리에 대해 AOT 컴파일을 실행합니다.

for i in /usr/local/lib/mono/*/mscorlib.dll; do mono --aot $i; done
for i in /usr/local/lib/mono/gac/*/*/*.dll; do mono --aot $i; done

위의 이미지 환경 내에서의 mono 설치 경로는 /usr/local에 있으므로 경로는 mono 실행 파일의 위치를 which 명령으로 확인하여 적절하게 변경해야 합니다. 참고로 GAC에 대한 AOT 컴파일은 시간이 오래 걸릴 수 있으며, 이 버전의 가상 환경에서는 .NET Framework 1.0이나 1.1 기준으로는 개발이 불가능하므로 버전을 업그레이드 하거나 base image로부터 구 버전의 mono를 설치하도록 수동 구성해야 합니다.

그리고 개별 어셈블리에 대한 AOT 컴파일은 다음과 같이 실행할 수 있으며, 실행 결과로 .so 파일이 생성되므로 AOT 컴파일의 효과를 위하여 항상 같은 위치에 배포될 수 있도록 배포합니다.

mono --aot Hello.exe
mono Hello.exe

마무리

지금까지 Windows Azure Linux VM에서 docker를 이용한 mono 개발 환경의 구축 방법을 살펴보았습니다. 언제든 원하는 때에 즉시 Linux VM을 만들 수 있다는 것 말고도, 한 번 만든 VM을 손상시키지 않으면서 환경을 독립적으로 구성할 수 있도록 하는 환경 상의 완결성을 제공하는 docker를 이용함으로서 최상의 리눅스 개발 환경을 체험할 수 있게 된 것은 참 좋은 일입니다.

그리고 한 가지 더 덧붙이면, docker를 이용하여 컨테이너를 만들 때 -v 스위치를 사용하여 호스트 파일 시스템과 링크를 연결할 수 있으므로, 컨테이너 셸 상에서 만든 파일을 쉽게 호스트로 반출하거나 반입할 수 있습니다. -p 스위치는 가상 NAT를 통하여 포트 리디렉션을 할 수 있는 방법을 제공하며, 양쪽 스위치의 자세한 사용법은 http://blog.docker.io/2013/07/docker-0-5-0-external-volumes-advanced-networking-self-hosted-registry/ 의 내용을 확인하기 바랍니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Azure Storage/Database2013. 10. 13. 21:00

Windows Azure Storage는 익히 잘 알려져 있는대로 Object Storage의 역할을 충실히 잘 수행할 수 있는 매우 높은 기능 수준을 가진 Cloud 기반 BLOB Storage입니다. 단순히 웹 기반의 파일 업로드와 다운로드만을 하는 컨테이너들의 집합으로 생각하기 쉽지만, 잘 활용하면 어렵지 않게 전송 보안과 간단한 DRM까지 한번에 달성할 수 있습니다. 그리고 이런 고급 기능 외에도 저수준의 입출력도 지원합니다.

덕분에 매우 유용한 조합을 이용할 수 있는데, 바로 SharpZipLib의 ZipFile 클래스와 Windows Azure Storage Library의 CloudBlobStream 클래스를 결합하는 것입니다. 방금 이야기한 저수준의 입출력을 위해서는 HTTP의 Byte Range Request와 비슷한 입출력 방법이 가능해야 하고 이를 지원하는 Stream 클래스가 있어야 하는데 이를 구현하는 것이 바로 http://msdn.microsoft.com/ko-kr/library/windowsazure/dd179440.aspx 에서 소개하는 x-ms-range 요청 헤더 (http://msdn.microsoft.com/ko-kr/library/windowsazure/ee691967.aspx)와 이를 사용하는 CloudBlobStream 클래스입니다.

우선 Windows Azure SDK Storage Library의 버전이 최신 버전으로 업그레이드가 되어야 합니다. NuGet 패키지 관리자를 최신 버전으로 업그레이드한 다음, 아래 그림과 같이 시험해보려는 프로젝트에 대해서 Windows Azure Storage 라이브러리 패키지를 설치합니다. 단, 이 작업을 하기에 앞서서 해당 프로젝트의 기준 .NET Framework 버전을 적어도 .NET Framework 4 Client Profile 이상으로 설정해야 합니다.

 

패키지를 설치한 다음, 아래와 같이 간단한 코드를 작성해보도록 하겠습니다. 강조표시한 부분은 환경에 맞게 변경해주셔야 하는 부분들입니다.

CloudStorageAccount account = new CloudStorageAccount(
    new StorageCredentials("accountName", "accessKey"),
    false);

var client = account.CreateCloudBlobClient();
var containerRef = client.GetContainerReference("example");

var blobRef = containerRef.GetBlockBlobReference("SampleDoc.docx");
var blobStreamAsync = blobRef.OpenReadAsync();
blobStreamAsync.Wait();

using (Stream srcStream = blobStreamAsync.Result)
using (ZipFile file = new ZipFile(srcStream))
{
    foreach (ZipEntry entry in file)
    {
        if (!entry.Name.StartsWith("word/media", StringComparison.OrdinalIgnoreCase))
            continue;

        Console.WriteLine("Extracting {0}...", entry.Name);

        using (Stream innerFile = file.GetInputStream(entry))
        using (Stream localFile = File.OpenWrite(Path.GetFileName(entry.Name)))
        {
            innerFile.CopyTo(localFile);
        }
    }
}

위의 코드는 Windows Azure Storage에 올라가있는 Microsoft Word 문서 파일 안에 들어있는 미디어 파일들의 목록을 조회하여 전체 Word 문서를 다운로드하지 않고 즉시 미디어 파일들을 추출하는 예제 프로그램 코드입니다. 여기서 중요한 것은 최소한의 I/O 요청만을 이용하여 ZIP 파일을 마치 로컬 하드 디스크에서 다루던 것과 동일하게 그 안에 압축되어있던 파일을 자유롭게 액세스할 수 있다는 점입니다.

아래는 실행 결과입니다.

 

 

그렇다면 궁금한 것이 있습니다. 실제 네트워크 트래픽은 어떻게 주고 받는 것일까요? Fiddler를 통하여 실제 네트워크 트래픽 상태를 확인해보도록 하겠습니다.

 

예상대로 Windows Azure BLOB Storage 서버에서 우리가 다루려는 BLOB 객체에 대한 요청이 이루어지고 있으며, 최초에는 파일에 대한 정보 확인을 위하여 보낸 요청에 대한 응답으로 200 코드를 반환하였습니다. 

그리고 후속 요청으로 특정 Byte Range에 대한 데이터만을 보내는 요청이 SharpZipLib의 ZipFile 클래스가 내부 스트림에게 Seek/Read 요청을 보내게 되어 발생하게 되고, 이것은 다시 Windows Azure Storage REST API에 맞게 번역되어 실제 HTTP 요청으로 바뀌어 전달됩니다. 그 결과 여기에 대한 응답으로 HTTP 206 응답 코드와 함께 특정 구간의 데이터에 대한 정보와 함께 바이너리 데이터가 다운로드됩니다.

뒤이어 나오는 요청들은 전부 이와 같은 형태로 Partial Request와 Partial Response로 구성되어있으며, BLOB 데이터가 변경되지 않는 한 계속 유효하므로 이렇게 수신한 데이터는 내부적으로 계속 재사용됩니다. 또한, 일정 단위의 Chunk를 내려받는 것이므로 너무 빈번하게 요청이 발생하지 않도록 트래픽에 대한 조절도 잘 되고 있다는 것을 알 수 있습니다.

결론

이 기법은 HTTP 표준을 기반으로 동작하는 것이므로, 제대로 구현이 되어있기만 하다면, Dependency Injection이나 Inversion of Control 등의 기법을 통하여 여러 Cloud Object Storage 상의 파일들을 마치 로컬에 있는 자원을 가져다 사용하는 것과 같이 투명하게 관리할 수 있습니다. 저수준의 I/O가 가능하므로 여기서 예로 든 ZIP 파일에 대한 부분 요청 이외에도 동영상이나 미디어 스트리밍 등에서도 활용할 수 있는 여지가 많고, 무엇보다도 중요한 것은 이 모든 요청이 REST API 이기 때문에 여전히 Windows Azure Storage의 컨테이너나 BLOB에 대한 보안 정책이나 Shared Access Signature 등의 요소와 유연하게 연동되므로, 리소스에 대한 시간 제한을 통하여 인프라의 능력을 이용한 DRM을 자연스럽게 구현할 수 있고, 중간 전송 매개체로 HTTPS를 사용하도록 결정하면 송수신 보안도 자동으로 해결되므로 유용한 면이 있습니다.

여기서 예로 든 Microsoft Word 문서의 활용은 기본이고, 만약 여러분이 필요로 하시는 ZIP 컨테이너 기반의 파일 I/O 작업을 지금 여기에서처럼 클라우드 상의 object storage 상으로 옮겨가서 작업하는 것도 가능하니 많이 활용하셔서 도움을 얻으시기를 바랍니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2013. 10. 12. 21:00

요즈음은 Infrastructure as a Service를 이용하여 VM의 Mobility를 통한 클라우드 서비스 사업자 간 이동 및 이전이 요즈음 주목 받고 있습니다. 익히 잘 알려진대로, Windows Azure의 경우 사설 혹은 기업 데이터센터 구축을 위하여 사용하는 Hyper-V 환경의 가상 PC를 Windows Azure로 진출시키거나 역으로 가져오는 등의 기능은 상당히 잘 알려져 있어서 많이들 이용하고 계실 것 같습니다.

그런데 Platform as a Service는 이런 부분에서 확실한 이동성을 보장하기 많이 어렵다는 것이 문제가 됩니다. 특히 비즈니스 로직을 내부에 많이 포함하고 있는 클라우드 응용프로그램일 수록 해당 클라우드 서비스에 종속적이기 때문에 클라우드 사업자간 이동이 훨씬 더 어렵습니다. 물론, 이를 극복하기 위하여 Dependency Injection이나 Inversion of Control을 이용하여 클라우드 사업자들이 제공하는 SDK의 공통 분모를 추출하여 그 대상으로 삼는 것도 가능한 전략이기는 하겠습니다만 사실 쉽지 않습니다.

좀 더 현실적이고 직관적인 방법이 없을까 많이들 고민하시는 데에 어느정도 도움이 될까 하여 한 가지 방안을 제시해 보겠습니다. 바로 ASP.NET과 Web Deploy를 이용한 개발입니다.

왜 ASP.NET과 Web Deploy를 사용하는가 - ASP.NET을 사용할 수 있는 환경의 다양성

PHP, Node.js, Ruby on Rails 등 웹 세계에서 유명한 프레임워크나 개발 환경이 많이 있습니다만 상대적으로 ASP.NET은 늘 저평가되어있습니다. 특히 ASP.NET을 버전 1.0~2.0 시절의 Web Form과 연결하여 선입견을 가지는 경우가 무척 많습니다. 그렇지만 이전부터 필자가 계속 강조해왔던 NuGet, Web Developer Express 등 다양한 OSS에 친화적인 기술들과의 결합과 ASP.NET MVC의 등장은 이 선입견에 묻혀서 거의 알려지지 않은 경우가 많습니다. (특히 국내에서는 더욱 그렇지요.)

그러나 이런 와중에 생각보다 ASP.NET의 입지는 넓습니다. Microsoft 기술과 가장 친화적이지 않을 것 같은 Amazon의 BeansTalk가 ASP.NET Web Deploy 패키지를 사용한 PaaS 배포 기법을 전면에서 지원하고 있으며, 사용 중인 환경이 Linux인 경우 다양한 방법으로 Mono ASP.NET 런타임과 결합하여 ASP.NET 웹 사이트를 호스팅할 수 있습니다. 그리고 Windows Azure는 Web Site와 Cloud Service를 이용하여 각각 웹 사이트를 호스팅할 수 있는 방법을 제공합니다. 멀리 가지 않아도 시중에 나와있는 웹 호스팅 서비스는 모두 FTP를 통한 ASP.NET 웹 사이트 배포까지 지원합니다. 수단은 얼마든지 많고, 남는 것은 전략의 수립에 관한 부분만이 남는 셈입니다.

왜 ASP.NET과 Web Deploy를 사용하는가 - 단일 코드 베이스 유지

ASP.NET을 이용하여 독립적으로 실행할 수 있는 Web Application Project를 만들어두면, Public Cloud만을 이용해서 서비스를 구축하였을 때 간간히 문제가 발생하는 특정 데이터센터, 혹은 특정 클라우드 서비스의 장애로 인해서 전체 서비스가 중단되는 사고로부터 좀 더 자유로워질 수 있습니다.

여러 위치에 분산된 응용프로그램을 배포하는 것은 기본적으로 매우 어려운 작업입니다. 그리고 이 어려운 작업의 난해함을 지수승으로 더 복잡하게 만드는 것은 바로 클라우드 서비스 사업자 간의 고유한 기능 집합 때문입니다. 이 문제를 해결하기 위해서는 사업자 간 이해 관계가 비교적 덜 연결되어있으면서도 구성의 차이가 거의 없는 기술을 택하는 것이 바람직한데, 여기에 들 수 있는 후보로는 ASP.NET을 포함하여 다수의 기술들이 있습니다. 그 중에서도 오늘 소개하려는 ASP.NET은 수준 높은 IDE 지원과 다양한 OSS 프로젝트와의 연계가 가능하기 때문에 유용한 점이 많습니다.

왜 ASP.NET과 Web Deploy를 사용하는가 - 배포 시의 문제점을 최소화

기능 상의 유용함 이외에도, 스스로 스케줄링을 해야 하는 Daemon Type의 서비스 프로세스가 아닌 RPC나 REST 형태의 시스템일 경우 ASP.NET을 사용하여 프로그래밍하고 Visual Studio의 지원을 받을 때의 큰 이점이 하나 더 있습니다. 바로 배포 시의 문제점을 최소화할 수 있다는 것입니다.

ASP.NET Web Deploy 및 관련 프로세스들은 패키지로 만들 때, 종속성에 관련된 모든 문제를 예방할 수 있도록, 웹 프로젝트와 연관성이 있는 모든 종속성 관계 상의 파일을 자동으로 복사하여 패키지에 포함시키는 정책을 사용합니다. 이러한 특징 때문에, ASP.NET MVC나 Razor의 최신 버전이 처음 .NET Framework가 배포된 이후에 바뀌더라도 최신 기능을 사용하면서도 배포 상의 DLL 버전 차로 인한 문제가 발생할 가능성이 높지 않습니다.

클라우드 서비스 별 배포 방법 - Amazon BeansTalk

우선 Amazon BeansTalk의 경우를 예로 들어보도록 하겠습니다. Amazon BeansTalk는 Visual Studio에 추가 기능으로 설치할 수 있는 Toolkit을 통한 배포/모니터링과 Management Console (Web)를 통한 패키지 파일 업로드 방식의 배포를 모두 지원합니다.

웹 프로젝트를 만들고, 아래 화면과 같이 배포 프로필을 Web Deploy 패키지로 만드는 것으로 설정한 다음, 지정된 위치에 패키지 파일을 만들도록 합니다. 패키지 파일은 ZIP 파일입니다.

만들어진 파일을 AWS Management Console로 이동하여 다음과 같이 업로드를 시작합니다.

업로드 완료 후 배포 프로세스가 시작되면 다음과 같이 진행 상황이 표시됩니다.

잠시 기다리면 다음과 같이 정상 배포가 완료되었음을 알리는 화면이 표시됩니다.

그리고 로드 밸런서 앞으로 부여된 FQDN 앞으로 접속하면 다음과 같이 로컬 개발 환경에서 개발할 때와 비슷한 응용프로그램이 실제 클라우드 서비스에서 실행 중인 것을 볼 수 있습니다.

BeansTalk의 멤버 노드로 참여하는 VM 인스턴스들이 있다면 여느 PaaS 플랫폼들과 마찬가지로 모든 배포를 자동화하여 처리하므로 배포 프로세스의 상당 부분을 쉽게 완료할 수 있습니다.

클라우드 서비스 별 배포 방법 - Azure Web Site

이번에는 Azure Web Site를 위한 배포 방법을 살펴보도록 하겠습니다. Visual Studio에서 앞의 경우와 마찬가지로 웹 게시 대화 상자를 띄운 다음, 가져오기 버튼을 클릭합니다.

 

처음 이 기능을 실행하면 배포 프로필을 한 번도 사용한 적이 없으므로 아래와 같이 빈 목록이 나타나게 됩니다. Windows Azure 구독 추가 링크 (드롭 다운 상자 아래)를 클릭합니다.

 

Windows Azure 구독 가져오기 대화 상자가 나타나면 구독 파일 다운로드 링크를 클릭합니다.

 

로그인 페이지에서 로그인을 완료하면 로그인한 Microsoft ID와 연결된 모든 Windows Azure Web Site 프로필 정보를 취합한 통합 프로필 파일의 다운로드를 시작하게 됩니다.

 

앞의 대화 상자로 되돌아와서, publishsettings 파일을 다시 지정하고, 가져오기 버튼을 클릭합니다. 잠시 기다리면 지정한 Live ID로 만든 여러 가입 상의 여러 Azure Web Site에 대한 정보가 한번에 나타납니다. 관리자 권한만을 가지고 있었다고 할지라도 여기에 한번에 나타나므로 손쉽게 배포를 진행할 수 있고, 이 과정 이후에 따로 웹 사이트를 새로 만들더라도 다시 이 대화 상자만 띄우면 목록이 새로 업데이트됩니다.

 

이와 같이 설정을 마무리하고 연결에 이상이 없는지 유효성 검사 버튼을 클릭하여 녹색 체크 마크가 나타나면 배포를 위한 연결이 성립된 것으로, 계속 진행해도 좋습니다.

 

클라우드 서비스 별 배포 방법 - Azure Cloud Service / Web Role

기존에 만들어진 ASP.NET 웹 사이트 프로젝트를 Web Role로 변환하여 내보내는 작업은 생각보다 어렵지 않습니다. 기술적인 고려 사항을 제외하면, Web Role용 프로젝트는 Beans Talk의 경우와 마찬가지로 Azure Cloud Service만을 위해서 무언가 꼭 추가해야 하거나 심각하게 변경해야 할 것이 전혀 없습니다.

Windows Azure Tools 최신 버전을 설치한 다음, 클라우드 서비스 프로젝트를 생성할 때 아래와 같이 아무것도 추가하지 않은 상태로 확인 버튼을 클릭합니다. 기존 프로젝트를 가져오기 위해서입니다.

 

그러면 멤버 역할이 없는 상태의 빈 클라우드 서비스 프로젝트가 만들어지게 됩니다. 이제 솔루션 탐색기의 역할 폴더를 오른쪽 버튼으로 클릭하고 아래 그림과 같은 순서로 팝업 메뉴를 접근합니다.

 

그러면 아직 지금 클라우드 서비스와 연결된 적이 없는 프로젝트의 목록이 나타나게 됩니다. 항목을 선택하여 클라우드 서비스 프로젝트로 가져옵니다.

 

정상적으로 가져오게 되면 다음과 같이 솔루션 탐색기의 클라우드 서비스 프로젝트 아래의 역할 폴더에 프로젝트 이름이 나타나면서 클라우드 서비스의 웹 역할로 등록됩니다.

 

이제 Azure Cloud Service로 배포하기 위하여 패키지를 만들 차례입니다. 패키지를 만들어서 Azure Management Portal을 이용하여 업로드를 해도 좋고, 사전에 인증서 및 계정 연동을 미리 구성하여 Visual Studio에서 진행해도 상관 없습니다. 여기서는 패키지 만들기 기능으로 배포를 해보겠습니다. 클라우드 서비스 프로젝트를 오른쪽 버튼으로 클릭한 다음 패키지 메뉴를 클릭합니다.

 

그러면 배포 대화 상자가 나타나게 됩니다. 각각의 드롭 다운 상자의 의미는 어렵지 않습니다. 서비스 구성이란 클라우드 서비스의 구성을 의미하는 것이고, 빌드 구성은 각 역할과 연결된 C#이나 VB.NET 프로젝트들의 빌드 구성을 의미하는 것으로 양쪽은 서로 독립적인 관계이므로 적절한 옵션을 선택합니다. 설정을 확인한 다음 패키지 버튼을 클릭합니다.

 

빌드 상의 오류가 없으면 탐색기 창이 열리면서 .CSCFG 파일과 .CSPKG 파일이 표시됩니다. 이 파일을 다루기 쉬운 위치로 이동시켜 Windows Azure Management Portal에서 클라우드 서비스를 만든 다음 게시합니다.

 

 

고려할 사항들

전통적인 웹 응용프로그램들과는 달리 클라우드 서비스들은 단일 인스턴스에서 실행하는 것 보다는 로드 밸런싱을 전제로 여러 인스턴스에서 실행하는 것을 기준으로 생각합니다. 그렇기 때문에, 전통적인 웹 기반 응용프로그램을 그대로 전환하는 것은 생각보다 쉽지 않습니다. 특히, 컴퓨터 자체적으로 업로드한 파일을 보관하거나, 서버 컴퓨터의 상태에 의존적인 웹 응용프로그램은 클라우드 기반의 서비스로 이동하기 전에 적절한 보완이 반드시 필요합니다.

그리고 여러 위치에 클라우드 서비스를 배포하고 관리하기 위해서는 자동화된 빌드, 배포, 모니터링 도구가 필요합니다. 각각의 개별 클라우드 서비스들이 제공하는 REST API를 이용하는 도구를 직접 만들 수도 있지만, 재미있는 것은 대다수의 클라우드 서비스 공급자들이 Windows에서는 PowerShell에 대응하는 모듈을 개발하여 배포하고 있다는 것이고, Unix나 Linux에서는 node.js의 클라이언트 기반 런타임을 개발하여 배포하는 일이 많다는 점입니다.

이러한 특징들을 이용하여, 여러 클라우드 서비스를 손쉽게 관리할 수 있는 노하우를 개발하여 여러분의 개발 및 운영 프로세스에 자연스럽게 통합시킬 수 있을 것으로 기대합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2013. 10. 5. 15:02

이 글을 읽기 전에 주의 사항 - 이 강좌는 기술적인 내용을 다루기 위하여 작성된 것으로, 여기서 소개하는 내용을 이용하여 스팸 메일을 대량 발송하는데 악용해서는 안됩니다. 또한 필자는 불법적인 소프트웨어 개발 의뢰로 오는 연락에는 회신하지 않습니다. 이 점 주의하여 주십시오.

소셜 네트워크 서비스나 다른 여러가지 의사소통 채널들이 많이 늘어났지만, 오랜 시간동안 변함없이, 그리고 지금까지도 널리 사용되고 꾸준히 활용되는 광범위한 메시징 서비스로 여전히 E-MAIL은 그 값어치를 인정받고 있고 중요성이 유지되고 있습니다.

그런데 요즈음은 원치 않는 메일 수신이 늘어나면서 메일이 정상적으로 도착하게 될 것인지 아닌지 불분명한 메시지 송신을 담보로 해야 하는 경우가 많습니다. 이는 스팸 메일 필터링 규칙이 까다로워진 것에 큰 원인이 있을 것입니다.

대규모로 메일을 보내면서도 안정적인 송신이 가능한 방법으로 요즈음은 대량 E-MAIL 발송 서비스를 많이 이용하곤 합니다. 여러가지 서비스들이 있을 수 있지만, 만약 Windows Azure를 사용 중인 경우, Windows Azure Add-on과 연동되는 SendGrid E-MAIL 서비스를 사용하면 간편하게 SMTP 발송 서비스를 사용할 수 있습니다. 특히 초기 개발을 위하여 사용할 경우 무료로 약 5만여통의 E-MAIL 발송을 테스트해볼 수 있습니다.

SendGrid 신청 방법은 쉽습니다. Windows Azure Management Portal에 접속하여, 신규 Addon 서비스 신청 (2013년 10월 현재 한국어 메뉴에서는 저장소라고 나타나는 부분) 메뉴를 클릭하여 다음과 같이 SendGrid 서비스 신청을 진행하면 됩니다. 무료 서비스를 택하여 계정을 생성할 수 있습니다.

서비스 신청이 완료된 후, SendGrid 서비스 항목에 대한 상세 페이지로 들어가면 다음과 같이 대시보드 화면이 나타납니다. 기본적인 서비스 연결 정보 확인 및 계약 관리를 이곳에서 할 수 있으며, 실제 서비스에 대한 속성은 SendGrid 측의 관리자 페이지로 이동하여 진행할 수 있고, 이 관리자 페이지는 현재 Windows Azure 계정과 1:1 관계로 대응되는 SendGrid 측에서 자동으로 생성한 사용자 계정과 연결되어 Single Sign On으로 연동됩니다.

하단의 도구 모음에서 관리 버튼을 클릭하면 다음과 같이 SendGrid 측의 관리자 페이지로 이동합니다. 

이 관리자 페이지에 등록된 개인 정보는 수동으로 다시 입력해주어야 합니다. 프로필 변경을 통해서 수동으로 변경 가능하며 정확한 정보를 입력해야 나중에 유료 계정으로 업그레이드할 때 문제가 발생하지 않습니다. 그 외에는 메일의 발신 상태, 발신 시 표시할 문구 및 부가 기능 설정 등을 관리할 수 있으므로 서비스 자체에 대한 속성은 여기서 설정하시면 됩니다.

연결 정보 버튼을 클릭하면 위와 같이 SMTP 서버 접속 정보가 나타납니다. 위 정보를 메모하시고 다른 곳에 유출되지 않도록 관리해야 합니다. 이제 C# 프로그램 코드를 이용하여 메일을 보내는 예제 코드를 한 번 만들어보도록 하겠습니다.

string connString = CloudConfigurationManager.GetSetting("DefaultStorage");
var account = CloudStorageAccount.Parse(connString);
var blobClient = account.CreateCloudBlobClient();

var getBlobReferenceFromServer = Task<ICloudBlob>.Factory.FromAsync<Uri>(
    blobClient.BeginGetBlobReferenceFromServer,
    blobClient.EndGetBlobReferenceFromServer,
    new Uri(o as string), null);
var blob = await getBlobReferenceFromServer;

try
{
    using (SmtpClient client = new SmtpClient("smtp.sendgrid.net", 587))
    using (MailMessage message = new MailMessage(
        new MailAddress("rkttu@somewhere.com", "보내는 사람 이름"),
        new MailAddress("someone@abc.com")))
    {
        string[] nameParts = blob.Name.Split(new char[] { '/' }, StringSplitOptions.None);
        string siteIdPart = nameParts[0];
        string userIdPart = nameParts[1];

        message.Subject = String.Format("[Xinics Commons - {0}] {1} has uploaded the content.", siteIdPart, userIdPart);

        message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(
            String.Format(@"
New content has arrived.

* Site ID: {0}
* User ID: {1}
* Media URL: {2}

", siteIdPart, userIdPart, o), null, MediaTypeNames.Text.Plain));
        message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(

            String.Format(@"
<p>New file has arrived.</p>
<ul>
<li>Site ID: {0}</li>
<li>User ID: {1}</li>
<li>Media URL: {2}</li>
</ul>

", siteIdPart, userIdPart, o), null, MediaTypeNames.Text.Html));

        client.Credentials = new NetworkCredential(
            "<SENDGRID 사용자 ID>",
            "<비밀 번호>");

        await client.SendMailAsync(message);
    }
}
catch (Exception ex)
{
    Trace.TraceWarning(ex.ToString(), "Exception");
}

클라우드 서비스를 통하여 수신한 BLOB 파일에 대한 정보를 특정 사용자에게 메일로 보내기 위하여 위와 같이 코드를 작성하였습니다. 여기서 굵게 강조표시한 항목들이 바로 연결 정보에서 나타난 부분으로 교체해야 하는 부분입니다.

SendGrid를 통하여 E-MAIL을 보내면 수신 거부 링크를 자동으로 첨부하여 보내줍니다. 수신 거부한 사용자들은 제외하고 메일 발송을 계속 할 수 있으며, 수신 거부 내역은 관리자 페이지를 통하여 쉽게 확인할 수 있습니다. 관리 목적으로 보내는 E-MAIL 말고도 마케팅 관련 메일을 보낼 때도 SendGrid를 사용하면 법률을 준수할 수 있습니다.

주의 사항 - 이 강좌는 기술적인 내용을 다루기 위하여 작성된 것으로, 여기서 소개하는 내용을 이용하여 스팸 메일을 대량 발송하는데 악용해서는 안됩니다. 또한 필자는 불법적인 소프트웨어 개발 의뢰로 오는 연락에는 회신하지 않습니다. 이 점 주의하여 주십시오.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2013. 3. 31. 12:58

안녕하세요. Windows Azure MVP 남정현입니다.

Windows Azure를 사용하면서 여러가지 서비스들을 많이 활용할 수 있지만, 역시 Windows Azure Platform을 제일 잘 설명할 수 있는 것은 확장성에 충분히 대응할 수 있는 유연한 아키텍처가 아닐까 싶습니다. 하지만 이러한 아키텍처를 어떻게 디자인하고 설계하고 수정해야 할지 개념을 잡기가 쉽지 않을 수 있는데요, 이러한 개념을 알기 쉽게 설명해주는 유용한 포스터를 하나 공유합니다.

아래 링크를 클릭하시면 포스터 PDF 파일을 내려받으실 수 있습니다. 포스터를 내려받아서 필요한 부분만을 읽어보시거나, 포스터 인쇄를 주문하셔서 잘 보이는 곳에 붙여놓고 활용하시면 좋을 것 같습니다. :-)

Windows Azure Scalability.pdf

감사합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2013. 3. 7. 15:52

안녕하세요. Windows Azure MVP 남정현입니다.

Windows Azure Cloud Service에서 실행되는 응용프로그램을 개발하는 과정에서 자주 필요성을 느끼게 되는 기능 중 하나는 지금 코드가 호스팅되는 위치가 실제 Windows Azure 데이터 센터 내인지, 에뮬레이터 내인지, 아니면 일반적인 서버 환경인지를 알고자하는 경우입니다. 이러한 위치 구분이 필요한 이유는 바로 코드 재사용성을 위해서인데, 정확하게 구분하기가 쉽지 않은 점이 있습니다.

여기에 대한 다양한 방법과 Workaround가 존재하지만 추천할만한 코드 Snippet이 있어서 글로 정리하여 올려봅니다.

RoleEnvironment.IsAvailable 속성

실제 Windows Azure Cloud Service 환경이거나 에뮬레이터 환경에서 실행되는 경우를 알아낼 수 있는 방법입니다. 이 방법은 Windows Azure 런타임을 사용할 수 있는지 없는지에 대한 구분으로 활용할 수 있고, 에뮬레이터인지 아닌지는 구분할 수 없습니다.

사용 예시

public static bool EnsureRunningInAzureOrDevFabric()
{
    return RoleEnvironment.IsAvailable;
}

RoleEnvironment.DeploymentId 속성

실제 Windows Azure Cloud Service 상에 패키지를 Deploy해서 실행 중인 경우 이 속성에 Guid 값이 부여되므로 .NET Framework FCL이 제공하는 System.Guid.Parse 정적 메서드를 사용하여 Guid로 파싱할 수 있습니다. 파싱에 성공한다면 실제 환경, 그렇지 않다면 에뮬레이터 환경으로 구분할 수 있습니다.

사용 예시

public static bool EnsureRunningInAzure()
{
    Guid guidId;
    return (RoleEnvironment.IsAvailable &&
        Guid.TryParse(RoleEnvironment.DeploymentId, out guidId));
}

한 번만 조회하기

최대한의 효율성을 기하기 위하여, 단순 작업이지만 같은 작업을 여러번 수행할 필요가 없겠지요. 논리적으로 생각해보면, 이와 같은 사항이 코드를 실행하는 실행 시점에서 변경될 일은 2013년 현재의 Windows Azure 플랫폼 스펙으로 볼 때에는 없습니다. 클라우드 서비스가 아닌 환경으로 실행 중인 가상 컴퓨터가 별도 VM으로 분리 이동하는 기능은 제공되지 않으며, 일반적으로 개발자 환경과 실제 데이터센터 환경 사이에 실시간으로 VM을 주고 받을 일 또한 없습니다. 따라서 위의 메서드에 대한 호출 결과를 정적 생성자를 호출하는 시점에만 부르거나 Lazy Initialization으로 다루더라도 전혀 기능에 이상이 없을 것입니다.

유틸리티 클래스로 만들기

아래의 소스 코드는 http://stackoverflow.com/questions/6160947/how-can-i-determine-if-i-am-running-locally-on-my-pc-or-on-the-cloud 에서 발췌한 것임을 밝혀둡니다.

using Microsoft.WindowsAzure.ServiceRuntime;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;


namespace Sample

{

    public static class CloudEnvironment

    {

        private static bool m_IsRunningAzure = GetIsRunningInAzure();


        private static bool GetIsRunningInAzure()

        {

            Guid guidId;

            if (RoleEnvironment.IsAvailable &&

                Guid.TryParse(RoleEnvironment.DeploymentId, out guidId))

                return true;

            return false;

        }


        public static bool IsRunningInAzure()

        {

            return m_IsRunningAzure;

        }


        private static bool m_IsRunningAzureOrDevFabric = GetIsRunningInAzureOrDevFabric();


        private static bool GetIsRunningInAzureOrDevFabric()

        {

            return RoleEnvironment.IsAvailable;

        }


        public static bool IsRunningInAzureOrDevFabric()

        {

            return m_IsRunningAzureOrDevFabric;

        }

    }

}



Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2013. 2. 26. 01:01

안녕하세요. Windows Azure MVP 남정현입니다.

간단하지만 간과하기 쉬운 팁을 하나 공유하려고 합니다. Windows Azure Cloud Service를 .NET Framework 기반으로 개발할 때 있을 수 있는 일에 대해 이야기하려고 합니다. Cloud Service에 Worker Role을 추가할 때, Worker Role의 진입점에 관련된 팁을 알려드리기 위하여 글을 씁니다.

Worker Role은 전통적인 .NET 기반 응용프로그램들과는 다르게, 클래스 라이브러리 형식의 어셈블리를 만들고, 그 어셈블리가 클라우드 서비스 패키지 파일에 들어가게 됩니다. Windows Azure Fabric Controller는 관리자가 제출한 클라우드 서비스 패키지 파일을 열어서 그 안에 들어있는 진입점 어셈블리를 찾아서, 해당 어셈블리 내에 존재하는 진입 클래스를 선택하여 서비스 기동을 시작하게 됩니다. 이 과정에서 사용하게 되는 것이 .NET Framework의 핵심 기능들 중 하나인 Reflection입니다.

만약 Worker Role로 만든 어셈블리 안에서 RoleEntryPoint를 기본 클래스로 정의한 클래스가 하나 이상 들어있다면 어떤 일이 벌어질까요? 오름차순으로 정렬했을 때 가장 먼저 열거될 수 있는 클래스만이 진입점으로 선택됩니다.

이러한 문제를 해결하기 위한 방법은 정리하면 다음과 같습니다.

  • 실제로 사용할 Entry Point 클래스 하나만을 Worker Role 어셈블리 안에 배치합니다.
  • 나머지 모든 RoleEntryPoint를 상속받는 클래스들은 다른 클래스 라이브러리에 만들어서 이동시킵니다.
  • Worker Role 어셈블리에서 새로 만든 클래스 라이브러리를 참조합니다.
  • 컴파일이나 런타임 오류가 발생하지 않도록 코드를 정리합니다.

그리고 이 문제가 더 부각되는 것은 Worker Role 어셈블리 안에서 상속 등의 기능을 사용하여 여러 Entry Point를 구현하게 될 경우입니다. 실제로 사용하고픈 Entry Point는 따로 있지만 이름의 순서 상 다른 진입점이 먼저 나오면 이상하게 동작하는 것 처럼 보이게 됩니다. 여기에, 만약 먼저 검색되는 Worker Role EntryPoint 클래스가 추상 클래스이거나 인수 없이 호출하는 기본 생성자를 제외시킨 경우 서비스가 전혀 실행되지 않을 수도 있습니다. 이런 경우 이 글의 내용을 참고하여 문제 해결을 시도해보기 바랍니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Azure Storage/Database2013. 2. 3. 15:16

안녕하세요. Windows Azure MVP 남정현입니다.

Windows Azure를 가지고 무엇을 할 수 있을까? 이 점에 대해서 궁금해하시는 많은 분들을 위하여 레시피 강좌 시리즈를 지속적으로 업로드하려고 합니다.

이번에 소개해드리려고 하는 내용은 요즈음 유행하는 HTML5 기반의 앱과 관련된 내용입니다. 서버의 렌더링을 필요로하지 않고 스스로 동작할 수 있는, 마치 앱과 같은 특성을 지닌 지능적인 HTML 페이지를 Windows Azure BLOB Storage위에서 호스팅하는 방법입니다.

사실 지금 소개해드리려는 내용은 굉장히 간단한 내용이지만, 활용하기에 따라서는 굉장히 유용한 레시피가 될 수 있습니다. 이벤트나 행사 웹 사이트와 같이 단순하지만 기간 내에 액세스가 폭증하는 페이지들을 호스팅해야 하는 요구 사항이 종종 있는데 이럴 때 활용하시면 일을 매우 단순하게 만들 수 있습니다.

정적 웹 사이트에 담을 내용 준비하기

정적 웹 사이트란 문자 그대로 웹 디자이너가 작업을 끝마친 시안 형태의 웹 페이지에서부터 ASP, PHP, ASP.NET, CGI, Python, Perl 등 생각할 수 있는 서버측 구성 요소를 하나도 들여오지 않고 jQuery나 Dojo 같은 자바스크립트 프레임워크들, 그리고 외부의 Open API만을 활용해서 온전하게 작동하는 웹 앱에 이르기까지 운영해야 할 서버 측의 비용을 고려하지 않고 만들 수 있는 모든 종류의 웹 사이트 및 웹 앱을 뜻합니다. 자바스크립트 세계의 발전에 따라 정적 웹 사이트의 의미도 크게 확장되었다고 볼 수 있습니다.

여기서는 jQuery Mobile을 이용하여 만든 간단한 웹 사이트를 Windows Azure Storage를 이용해서 호스팅하도록 해보겠습니다. 소개하는 내용이 아니더라도 여러분이 손수 만든 개인 모바일 홈페이지도 괜찮고 무엇이든 시험해볼 수 있는 것이면 됩니다.

  • 준비물 1: CloudBerry Client for Windows Azure BLOB Storage (Pro 버전 대신 Freeware를 설명합니다.)
  • 준비물 2: jQuery Mobile 패키지 파일
  • 준비물 3: 여러분이 올릴 간단한 웹 페이지 파일 및 이미지 파일

CloudBerry Client for Windows Azure BLOB Storage 설치하기

CloudBerry Client는 여러 종류의 Windows Azure BLOB Storage 클라이언트 중 다루기 쉽고 간편한 인터페이스를 제공하는 무료 클라이언트입니다. CloudBerry Client는 Windows Azure 이외에도 KT UCLOUD Biz Storage 클라이언트와 같은 OpenStack Client도 지원합니다.

http://www.cloudberrylab.com/ 웹 사이트에 방문하시면 메인 페이지에 CloudBerry Explorer Freeware라는 이름의 다운로드 링크 컬렉션이 보일 것입니다. 여기서 for Windows Azure를 선택하여 이번 레시피에서 설명하는데 필요한 도구를 다운로드하고 설치합니다.

프리웨어이지만 사용자 등록을 권하는 부분이 있는데, 지속적으로 이 도구를 사용하게 될 것을 감안하여 재량껏 등록하여 사용하기 바랍니다. 등록하지 않고 진행해도 사용에는 큰 지장은 없을 것입니다.

설치 후 아래와 같이 프로그램이 나타나는지 확인합니다.

계정 정보 등록하기

새로운 계정 정보를 등록하려면 아래 그림과 같이 File 메뉴의 Azure Blob Storage Accounts 메뉴를 선택합니다.

아래와 같이 대화 상자가 나타날 것입니다. Add 버튼을 클릭합니다.

아래와 같이 계정 정보 입력 대화상자가 나타나는지 확인합니다.

  • Display name: 이 프로그램 상에서 나타낼 항목 이름으로 자유롭게, 알아보기 쉬운 이름으로 입력합니다.
  • Account: Windows Azure 저장소의 ID를 입력합니다. URL을 보면 <계정 이름>.blob.core.windows.net와 같은 형태로 구성되어있는데 여기서 <계정 이름>에 해당하는 ID를 입력합니다.
  • Shared Key: Windows Azure 관리 포털에서 나타나는 이 저장소에 대한 Shared Key를 입력합니다. Primary Key나 Secondary Key 중 하나를 입력하면 됩니다. 보안 향상을 위하여, 서비스 구성을 위해 활용하는 Key와는 다른 여분의 Key를 이곳에 설정하는 것이 좋습니다. 이렇게 하여 불시에 이 Key를 갱신하여 유출 사고 등에 유연하게 대처할 수 있게 됩니다.
  • Use SSL: SSL 통신을 사용할 지의 여부를 결정합니다.
  • Development Storage: 실제 서비스가 아니라 Windows Azure Storage Emulator로 연결할 경우 이 항목을 체크합니다.

계정 정보를 확인하려면 http://manage.windowsazure.com/ 으로 이동하여 저장소 계정 화면에 대한 대시 보드를 아래와 같이 확인합니다. 그 다음 하단의 도구 모음에서 Manage Keys 버튼을 클릭합니다.

아래와 같이 모달 대화 상자가 나타나면 Storage Account Name을 복사하시고, Primary Access Key 또는 Secondary Access Key 중 하나를 복사하여 위의 대화 상자에 입력하도록 합니다.

모든 설정이 완료되면 Test Connection 버튼을 클릭하여 연결이 잘 되는지 확인합니다. 연결에 성공하면 아래와 같이 대화 상자가 나타날 것입니다.

jQuery Mobile 패키지 준비하기

기본적으로 jQuery Mobile 패키지 파일을 CDN에서 받아서 이용하는 방법이 편리합니다. 이렇게 하면 jQuery Mobile 다운로드에 관한 트래픽을 우리쪽 서버가 아닌 다른 위치의 CDN으로 분산시킬 수 있으므로 트래픽 관련 비용 절감에 도움이 되기도 합니다. 여기서는 jQuery Mobile 패키지를 우리쪽 서버에 업로드하는 것을 기준으로 예제를 만들어 보도록 하겠습니다.

http://jquerymobile.com/download/ 웹 페이지에 접속하여 아래와 같이 Latest Stable Release를 찾아 JavaScript와 CSS 파일 패키지를 Minified Version으로 다운로드하기 바랍니다. 링크를 클릭하면 저장이 아니라 파일이 열리는 동작으로 다운로드가 발생할 수 있으므로 링크를 오른쪽 버튼으로 클릭하고 다른 이름으로 저장 기능을 사용하여 저장하기 바랍니다.

그리고 jQuery Mobile이 필요로하는 jQuery 라이브러리 파일도 가져와야 합니다. http://jquery.com/download/ 웹 페이지에 접속하여 아래와 같이 Minified Version을 다운로드합니다.

NOTE: 최근에 릴리즈한 1.9.x 버전의 경우 jQuery Mobile과 호환성 문제가 있을 수 있으므로 1.8.x 릴리즈를 다운로드해야 할 수 있습니다. 1.9.x 버전이 작동하지 않을 경우 1.8.x 버전을 사용하여 진행할 수 있습니다.

컨테이너를 만들고 권한 설정하기

이제 컨테이너를 만들고 여기에 파일을 업로드할 차례입니다. 다시 CloudBerry Storage Explorer로 되돌아가서 오른쪽 패널의 Source 드롭 다운 상자에서 방금 추가한 계정을 선택하여 접속을 시도합니다. 

Windows Azure Storage는 전통적인 웹 호스팅 환경과는 다르며, 기본적으로 1계층의 컨테이너만을 지원합니다. 그리고 컨테이너보다 더 깊이있는 레벨의 폴더 계층을 형성하려면 올리는 파일의 이름에 경로 구분을 위한 문자 ('/')를 포함시켜 폴더처럼 보이게 하는 방법을 사용하게 됩니다.

API에서 폴더를 탐색한다는 것은 이러한 특성에 따라 실제 폴더로 스택 자료 구조를 이용해서 탐색하는 방식이 아니라, Where Clause를 이용할 때 사용할 수 있는 Prefix Matching 기법을 사용하게 됩니다. 즉, 같은 Prefix를 보유하는 컨테이너 내의 파일들은 논리적으로 같은 폴더에 있는 것으로 취급이 가능합니다.

컨테이너를 만들기 위해서는 아래 그림과 같이 오른쪽 편의 도구 모음을 클릭합니다.

아래와 같이 대화 상자가 나타나면 컨테이너의 이름을 입력하고 권한을 설정합니다.

위의 권한들에 대해 각각 내용을 살펴보면 다음과 같습니다.

  • Full public read access: 이 컨테이너의 URL로 접속하면 컨테이너 안에 무슨 파일이 들어있는지 목록을 조회할 수 있는 기능과 더불어 모든 파일에 대해 다운로드 기능을 제공함을 의미합니다.
  • Public read access for blobs only: 이 컨테이너의 URL로 접속하면 권한이 없다는 오류 메시지가 나타나고, 대신 이 컨테이너 안의 정확한 파일의 URL을 알고 있는 경우 해당 파일은 다운로드가 가능함을 의미합니다.
  • No public read access: 컨테이너이든 그 안에 들어있는 파일이든 인증을 거치지 않고는 읽을 수 없도록 보호함을 의미합니다.

위의 세 가지 옵션 중에서 지금 우리가 선택하려는 것은 두 번째 옵션으로, 정적 웹 호스팅에서 어떤 파일이 들어있는지 사용자가 확인할 필요 없이 개별 URL에 대해서만 안다면 자동으로 모든 서비스가 제공되므로 파일에 대해서만 공개하도록 만들 것입니다.

파일 업로드하기

여기서는 정적 웹 호스팅을 간단하게 테스트해볼 목적으로 1계층 컨테이너 안에 같은 파일들을 넣어보려고 합니다. 여러분의 컴퓨터에서 아래와 같이 파일을 준비하시면 됩니다.

그리고 위의 index.html 파일의 소스 코드는 아래와 같습니다.

이제 위의 소스 코드를 Azure Blob Storage로 업로드합니다. 아래와 같이 파일이 업로드된 것을 확인합니다.

결과 확인하고 QR코드로 만들어 배포하기

이제 마지막으로 올라간 파일이 잘 작동하는지 확인할 차례입니다. 위의 파일들 중 index.html 파일을 오른쪽 버튼으로 클릭하여 URL을 확인합니다.

아래와 같이 대화 상자가 나타나면 Copy to clipboard 버튼을 클릭하여 주소를 복사하고 웹 브라우저에서 열어보도록 합니다. (혹은 Open link 버튼을 눌러도 됩니다.)

웹 브라우저에서 아래와 같이 잘 나타나는지 확인합니다.

이제 이 URL을 QR코드로 만들기 위하여 http://qr.naver.com/ 으로 접속하여 QR코드를 만들면 모바일 웹 사이트 구축이 완료됩니다.

더 나아가기

만약 폴더 구조를 유지하면서 파일 업로드를 하기 원한다면, Storage Explorer에서는 폴더를 직접 생성하는 기능이 없지만, 미리 로컬에서 만든 폴더째로 한꺼번에 업로드하면 자동으로 폴더를 생성하게 됩니다.

그리고 Windows Azure CDN 노드를 추가하면 이 상태 그대로 CDN 서비스를 받을 수 있습니다. CDN 엣지 노드 형성은 2013년 2월 현재 신규 포털이 아닌 구 버전의 포털 http://windows.azure.com/ 에서 관리할 수 있습니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

IaaS2013. 2. 3. 02:19

안녕하세요. Windows Azure MVP 남정현입니다.

오늘 소개하려고 하는 내용은 Windows Azure Virtual Machine 서비스를 통해서 Windows Server를 처음 만들면 해주어야 하는 가장 기본적인 작업인 지역 및 언어 설정에 관련된 내용입니다. 이 부분이 빠지게 되면 데이터베이스 등을 이용할 경우 시간이나 지역 정보가 일치하지 않아 데이터 정합성에 문제가 발생할 가능성이 있으므로 사소하지만 꼭 해야 하는 중요한 작업이기 때문에 알기 쉽게 정리해서 올려드리려고 합니다. 이번 레시피에서는 Windows Server 2012를 기준으로 설명합니다.

언어 팩 설치하기

이전 버전의 Windows에서는 별도의 Multilingual User Interface Pack (MUI Pack)을 구해서 시스템에 확장팩으로 설치하여 기본적인 한국어 IME 이외에 도움말, 대화 상자 등에 표시할 UI를 업데이트했었습니다. 그러다가 Windows Server 2012에서는 이러한 MUI Pack을 공개적으로 개방하기 시작하였는데, 클래식 제어판 (control.exe)에 들어가서 언어 애플릿을 선택하면 원하는 언어의 우선순위를 정할 수 있습니다. 그리고 원하는 언어를 추가한 다음, MUI Pack을 직접 설치할 수도 있습니다.

Windows Server 2012 인스턴스에 원격 데스크톱을 이용하여 로그인한 다음, 제어판을 시작합니다. 제어판을 시작하는 방법은 Windows + R 키를 입력하여 control 명령어를 입력하거나, 화면의 좌측 하단 구석을 마우스 오른쪽 버튼으로 클릭하여 나타나는 메뉴를 이용하는 방법이 있습니다.


그 다음, 제어판의 여러 항목들 가운데에서 Language 항목을 선택하여 언어 설정으로 이동합니다.

바뀌는 화면에서 현재 영어만 지원하도록 구성된 모습을 볼 수 있을 것입니다. 아래 화면과 같이 나타나면, Add Language 버튼을 클릭하여 새 언어 설정을 추가합니다.

추가할 수 있는 여러 언어들이 나타날 것입니다. 현재 표시 언어가 영어이고 영어로 한국어를 표현하는 이름인 Korean의 K를 찾아 내려가다보면 아래 그림과 같이 Korean 항목을 찾을 수 있습니다. 이 항목을 추가합니다.

아래 그림과 같이 한국어가 추가된 것을 확인한 다음에는 한국어가 가장 위로 올라오도록 Move Up 버튼과 Move Down 버튼을 적절히 조작하여 언어의 우선 순위를 변경합니다.

우선 순위 조정이 끝나면 Options 링크를 클릭하여 세부 설정으로 이동합니다.

저의 경우, 이전에 한국어 언어 팩을 이미 설치했던 적이 있어서 다른 언어의 스크린 샷을 가져와서 설명을 드리려고 합니다. 언어 팩이 설치되어있지 않은 상태라면 아래와 같이 Download and install language pack이라는 링크가 보이는데, 이 링크를 클릭해서 화면 UI 상의 언어가 업데이트되게 할 수 있습니다.

언어 팩 설정이 끝났으면 다시 로그인해서 아래 그림처럼 한국어로 서버 관리자 프로그램이 실행되는지 확인합니다.

일반 Win32 응용프로그램을 위한 설정 업데이트

기본적인 표시 언어 설정 이외에 기본 로캘 세트를 어느 지역으로 할 것인지는 따로 한 번 더 설정이 필요합니다. .NET이나 Java 등의 프로그래밍 언어를 사용하여 만들어진 소프트웨어나 서비스의 경우 큰 영향을 받지 않지만, Visual C++이나 Delphi 혹은 Pascal 등의 언어를 기반으로 컴파일된, 유니코드를 사용하지 않도록 빌드한 일부 Win32 응용프로그램의 경우 이 설정이 중요할 수 있습니다.

이번에도 제어판으로 이동합니다. 비슷한 항목처럼 보일 수 있는데 이번에는 Language (언어) 대신 Regional Settings (국가 또는 지역) 설정을 선택합니다. 둘 사이를 개념적으로 구분하는 기준은, 언어는 운영 체제 위에서 실행되는 프로그램들의 언어에 관한 것으로 통화, 길이, 도량, 무게 등의 지역 설정을 제외한 부분입니다. 그리고 국가 또는 지역 설정에서 취급하는 것은 언어보다는 앞서 언급한 통화, 길이, 도량, 무게, 전화 번호 체계 등과 같은 규칙에 관련된 것들입니다.

관리자 옵션 탭을 클릭했을 때 "유니코드를 지원하지 않는 프로그램용 언어" 그룹 안의 언어 선택이 "한국어(대한민국)"이 아닌 경우 시스템 로캘 변경 버튼을 클릭하여 해당 언어를 선택합니다. 변경이 발생하면 서버를 다시 시작해야하므로 관리 작업 수행 시 변경하는 것이 좋습니다. 그리고 현재 표시 언어 설정을 시스템 전반에 확산시켜야 할 필요가 있을 때 여기에 와서 "설정 복사" 버튼을 클릭하면 간단히 해결됩니다.

날짜 및 시간대 설정 변경하기

여러분이 호스팅하려는 응용프로그램에서 시간대에 대한 정보를 같이 저장하고 관리하는 경우 이 설정은 필요하지 않을 수 있습니다. 그러나 대개의 경우, 이러한 시간대 정보가 항상 동일할 것이라는 전제 아래에서 날짜와 시간 정보를 관리하게되어 Windows Azure나 Amazon Web Service와 같이 해외에 데이터센터를 두는 곳에서 실행하려는 경우 문제가 될 가능성이 큽니다.

날짜를 맞추기 위해서는 시간대 설정부터 확인하여야 하는데 단계별로 진행하면 어렵지 않습니다. 제어판으로 다시 이동해서 날짜 및 시간 설정을 클릭합니다,

날짜 및 시간 탭에서 표준 시간대 설정이 UTC +09:00 서울로 되어있는지 확인하고 그렇지 않은 경우 변경합니다.

이어서 시간 자동 동기화 기능을 사용하여 가상 환경에서 실행되는 컴퓨터의 특성에 의해 발생할 수 있는 시간 동기화 문제를 예방하도록 합니다.

인터넷 시간 서버와 동기화 체크 상자가 체크되도록 하고, 서버는 time.windows.com을 사용해도 무난합니다. 이 상태에서 지금 업데이트 버튼을 동기화되었다는 메시지가 나올 때 까지 반복합니다. UDP 연결이므로 한 번에 동기화가 되지 않을 수 있습니다.

결론

이 작업을 마무리하고난 다음에는 한국어 버전의 Windows Server 2012를 사용하는 것과 거의 동일한 환경을 얻을 수 있습니다. 이 상태에서 기존에 여러분이 사용하던 서버 응용프로그램들을 Azure의 IaaS 기반으로 쉽게 마이그레이션하고 작업을 마무리할 수 있을 것입니다.

긴 글 읽어주셔서 감사합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2013. 2. 1. 11:20

 

top.jpg

Windows Azure 클라우드 서비스를 무료로 체험하실 수 있는 절호의 기회!
온라인 캠프 참여 후, 후기만 작성하면 Microsoft 무선 마우스!! 최우수 후기로 선정되면 XBOX360 Kinect!!!
온라인으로 언제 어디서나 Azure를 만나는 Windows Azure 커뮤니티 온라인 캠프, 지금 바로 참여하세요!
but01.jpg
Windows Azure 커뮤니티 온라인 캠프
참가대상 Windows Azure 체험을 원하시는 커뮤니티 회원
(선착순 20~30명 마감, 중복 참여 가능)
신청방법 Onoffmix에서 참석 신청 이용
참여자발표 온오프믹스 웹 페이지 공지 후 개별 참석 메일 전달
캠프기간 2013년 3월 6일(수) 오후 6시 ~ 2013년 3월 8일(금) 오전 9시
캠프미션 [2기 5차] Windows Azure 웹사이트
Azure 포털에 만들어진 Windows Azure 인스턴스들을 이용해 체험(참석자 대상 메일 전달)
후기응모기간 2013년 3월 10일(일) 24:00까지 후기를 적어 주셔야 합니다.
후기응모방법 Azure 커뮤니티에서 지정한 게시판에 후기를 작성해 주시면 됩니다
- 5차 캠프 후기 작성 위치 - Windows Azure Cafe: [Azure 사용 후기 게시판]
온라인 캠프 진행 형식
메일을 통해
전달된 Microsoft
계정으로
Windows Azure
관리 포털에
로그인
bullet01.jpg
Azure 포털에
기 생성된
다양한
클라우드
서비스
체험
bullet01.jpg
캠프
기간 내에
Windows Azure
서비스를
체험하고
후기 작성!
bullet01.jpg
Microsoft
무선 마우스
받고,
XBOX360 Kinect
최우수 후기
선정 기다리기
gift.jpg
title01.jpg
Windows Azure 동영상 강좌 및 관련 Q&A 게시판을 참고하시면 더 다양하고 즐거운 캠프를 즐기실 수 있습니다.
Windows Azure
동영상 강좌
arrow01.png
 
1기 캠프 사용기
살펴보기
arrow01.png
 
Windows Azure
Q&A
arrow01.png
 
SQL Server 2012
Q&A
arrow01.png
 
Windows Server
2102 Q&A
arrow01.png
 
 
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2012. 12. 6. 00:25

"Azure Camp @ 인하대 - 리눅스, Windows Azure를 만나다" 세미나를 2012년 12월 6일 오후 2시부터 약 1시간 동안 인하대학교 하이테크 001호에서 진행할 예정입니다. 관심있는 인하대 학우 여러분들의 많은 참여 부탁드립니다.

발표 자료 미리 보기: http://sdrv.ms/TFqg0P

ps. 발표 행사 후에는 경품 추첨을 통해서 4권의 책을 선물로 나누어드릴 예정입니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

IaaS2012. 12. 3. 22:32

안녕하세요. Windows Azure MVP 남정현입니다.

Windows Azure Virtual Machine에서 리눅스를 지원하는 것은 다들 잘 알고 계실 것입니다. Ubuntu, CentOS, RHEL, Suse Linux 등을 이미 지원하고 있고 앞으로 개발 진척 상황에 따라서 더 많은 배포판을 지원해 나가게 될듯 합니다. 이번 강좌에서 소개하려고 하는 내용은 Windows Azure Virtual Machine에서 리눅스를 사용하면서 Apache 2 + PHP 5 + Cubrid + XE의 조합으로 XpressEngine 기반의 웹 사이트를 만드는 방법에 대한 것입니다. 익히 알고 계시는대로 Cubrid는 국산 오픈소스 데이터베이스로 다양한 적용 레퍼런스를 가지고 있는 믿음직한 솔루션입니다. 충분한 테스트와 검증이 필요하겠으나, 첫 설치 과정과 기본적인 동작에서 Cubrid는 Windows Azure Virtual Machine 환경에서 안정적으로 잘 작동하고 있습니다.

ps. 2012년 초반에 문제가 되었던 Windows Azure Virtual Machine의 디스크 I/O 관련 이슈, 부팅 후 일정 시간이 지난 다음에 갑작스럽게 Kernel Panic이 찾아오는 현상은 이 글을 쓰는 현 시점에서 해결된 상태입니다.

업데이트: SkyDrive에 아래 60장의 스크린 샷을 모아서 XPS 문서와 ZIP 파일로 업로드하였습니다. 요약해서 보고 싶으신 분들께 도움이 될까하여 공유합니다.

링크 바로가기: http://sdrv.ms/TGXhWs

60장의 그림과 함께하는 설치 과정 따라하기

1. Windows Azure Virtual Machine 베타 프로그램의 신청 여부를 확인하고, http://manage.windowsazure.com/ 에서 하단의 NEW 버튼 클릭 -> Compute 클릭 -> Virtual Machine 클릭 -> Quick Create 순으로 클릭합니다.

* DNS 이름을 지정합니다.
* Ubuntu 12.04 LTS (혹은 다른 Ubuntu 이미지도 무관합니다.)를 선택합니다.
* 적정한 Instance Size를 선택합니다.
* 사용자 ID가 azureuser 임을 기억하시고 비밀 번호를 새로 지정합니다.
* 데이터센터 위치는 대한민국 접속자 기준으로 East Asia를 선택하는 것이 유리합니다.

모든 정보를 입력하면 Create Virtual Machine 버튼을 클릭하고 잠시 기다립니다.

2. 새 Windows Azure Virtual Machine과 Storage가 생성된 것을 확인하면 만들어진 Virtual Machine을 선택하여 상세 관리 페이지로 이동합니다. 

3. Dashboard 화면의 오른쪽 Quick Glance 섹션에서 SSH Details 항목의 접속 주소와 포트 번호를 확인합니다. 이 접속 정보를 사용하여 여러분이 선호하는 Secure Shell 지원 Telnet 프로그램으로 접속을 시도합니다. Windows 환경에서 널리 사용되는 프로그램은 Putty이며, http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html 에서 내려받아 설치할 수 있습니다. 

4. Putty를 실행하고, Host Name 입력 상자와 Port 입력 상자에 접속 정보를 입력한 후 Connection type은 SSH로 선택하고 Open 버튼을 클릭합니다. 필요한 경우 Saved Sessions 입력 상자 아래에 새로운 엔트리 이름을 입력하고 Save 버튼을 클릭하면 다음번에 리스트 상자에서 저장된 항목을 더블 클릭하여 바로 연결을 시작할 수도 있습니다. 

5. 처음 원격 서버에 접속하면 임의로 생성한 RSA2 지문 키 값의 유효성 여부를 놓고 경고하는 대화 상자가 나타나게 됩니다. 예 (Yes) 버튼을 클릭하여 항상 이 값을 수락하도록 설정을 저장합니다. 

6. 사용자 ID는 azureuser로, 암호는 Quick Create 당시 지정한 암호를 입력하여 로그인합니다. 

7. 지금부터 수행하려는 작업들은 줄곧 권한 상승을 필요로 하기 때문에 작업의 효율성을 위하여 셸 자체를 권한 상승시키려고 합니다. sudo /bin/bash 명령을 실행하여 BASH 셸을 권한 상승 시킨 상태에서 실행합니다. 사용자 비밀 번호를 물어보는 경우 다시 입력합니다. 

8. vi /etc/hostname 명령어를 입력하여 /etc/hostname 파일을 아래와 같이 FQDN (Fully Qualified Domain Name) 이름으로 수정합니다. 초기값은 단순 호스트 이름으로만 되어있었을 것인데 이 이름을 앞에서 접속하기 위하여 사용한 전체 주소로 바꾸어주면 됩니다.

* VI에서 텍스트 편집 모드로 들어가려면 처음 상태에서 i 키를 누릅니다.
* 텍스트를 편집하고난 다음에는 Esc 키를 눌러 명령 모드로 전환합니다.
*  :wq! 를 입력하여 파일을 저장하고 VI를 닫습니다.

9. vi /etc/hosts 명령어를 입력하여 /etc/hosts 파일에 위에서 /etc/hostname에서 추가한 FQDN 이름에 대한 localhost 엔트리를 새로 추가합니다. VI에서의 파일 편집 방법은 8번 단계의 부연 설명을 참고하십시오. vi 사용이 익숙하지 않다면 nano 혹은 emacs 등의 유틸리티도 대안이 될 수 있습니다.

10. 새로 변경한 설정을 반영하기 위하여 service hostname start 명령을 입력합니다. 

11. SSL 인증서 갱신을 위한 유틸리티의 설치가 필요합니다. apt-get install ssl-cert 명령을 입력합니다.

12. 인증서 갱신을 위하여 make-ssl-cert generate-default-snakeoil --force-overwrite 명령어를 입력합니다. 

13. 이제 Apache HTTP Server를 설치할 차례입니다. apt-get install apache2 명령어를 입력합니다. 

14. PHP5를 설치합니다. apt-get install php5 명령어를 입력합니다. 

15. XpressEngine은 PHP GD 라이브러리의 기능을 활용합니다. GD 라이브러리는 .NET Framework의 GDI+가 ASP.NET이나 일반 응용프로그램을 위하여 해 줄 수 있는 백그라운드 이미지 렌더링에 대한 기능과 거의 일치하는 것으로 동적 이미지 생성 작업에 꼭 필요합니다. apt-get install php5-gd 명령어를 입력합니다.

16. Cubrid 측 Ubuntu Repository를 가져오기 위하여 Repository Entry를 수정해야 하는데 이를 위한 유틸리티를 설치하기 위하여 apt-get install python-software-properties 명령어를 입력합니다. 

17. add-apt-repository ppa:cubrid/cubrid 명령어를 입력하여 Cubrid Database 및 관련 구성 요소를 apt-get 명령어로 설치할 수 있도록 리포지터리 정보를 시스템으로 가져옵니다. 

18. 리포지터리 정보를 새로 내려받아 병합하기 위하여 apt-get update 명령을 수행합니다. 

19. 큐브리드 데이터베이스의 설치를 위하여 apt-get install cubrid 명령어를 실행합니다. 

20. PHP5에 큐브리드 데이터베이스 드라이버 설치를 위항 apt-get install php5-cubrid 명령어를 실행합니다. 

21. 큐브리드 데이터베이스의 환경 변수 반영 등 여러가지 부수적인 작업을 위하여 Windows Azure Virtual Machine의 리눅스 인스턴스를 shutdown -r now 명령어로 재시작합니다. 시스템 재 시작에는 얼마 시간이 걸리지 않습니다. 

22. 약 3~5분 정도 뒤에 아래 그림과 같이 PuTTY 창의 제목 표시줄을 오른쪽 버튼으로 클릭하여 Duplicate Session 혹은 Restart Session 메뉴를 클릭하면 같은 접속 정보를 사용하여 다시 접속을 시도합니다.

23. 다시 로그인합니다. 

24. 큐브리드 데이터베이스의 환경 설정을 위하여 전용 셸로 세션을 바꿉니다. sudo su -s $SHELL cubrid 명령어를 입력하고 azureuser 사용자의 비밀 번호를 다시 입력합니다.

* 주의: 이 명령어는 CUBRID 데이터베이스의 환경 변수 설정이 시스템 전체에 반영되지 않은 경우 작동하지 않습니다. 그런 경우 21단계의 명령어 shutdown -r now 명령어를 사용하여 시스템을 다시 시작해야 합니다. 권한이 없다고 나오는 경우 sudo shutdown -r now 명령어를 이용하여 권한 상승을 요청합니다.

25. cubrid service start 명령어를 입력하여 큐브리드 핵심 서비스를 시작합니다. 그리고 cubrid createdb xe 명령어를 입력하여 새 데이터베이스 'xe'를 생성합니다. 데이터베이스의 초기 크기는 512MB로 만들어지며 이 과정에서 시간이 다소 걸릴 수 있습니다.

26. cubrid server start xe 명령어를 입력하여 25단계에서 만들어진 데이터베이스 xe를 활성화시킵니다.

27. 새로 만들어진 xe 데이터베이스의 dba 계정 비밀 번호 변경을 위하여 csql -u[사용자 ID] [데이터베이스 이름] 형식으로 명령어를 입력합니다. 이번 강좌의 내용을 기준으로 하면 csql -udba xe 명령어를 입력하면 됩니다. 

28. CUBRID SQL Interpreter 배너가 출력되는 것을 확인할 수 있습니다. 이제 C-SQL 명령어를 입력해야 하는데 alter user dba password '[사용할 비밀 번호]'; 명령어를 입력합니다. 

29. 정상적으로 명령이 수행되었음을 확인한 다음 ;ex 명령어를 입력하여 CSQL 세션을 닫습니다. 

30. 이제 Apache HTTP Server의 디렉터리 컨텐츠를 구성해야 합니다. 정확한 디렉터리 위치를 알아보기 위해서 /etc/apache2 디렉터리로 이동한 다음 'DocumentRoot' 지시자를 포함하는 파일들의 내용을 grep -nr 'DocumentRoot' * 명령어로 검색해봅니다. 결과가 /var/www로 나타나므로 실제로 해당 위치로 이동해야겠군요.

31. 위치로 이동하기에 앞서 CUBRID 셸을 exit 명령으로 빠져 나옵니다. 그 다음 다시 원래의 셸에서 sudo /bin/bash 명령으로 권한 상승을 시도합니다.

32. 이제 cd /var/www 명령어를 입력하여 Apache HTTP Server의 기본 Contents 디렉터리로 이동합니다. 그리고 이곳에서 PHP의 정상 설치 여부를 확인하기 위하여 cat > test.php 명령어를 입력하여 표준 입력 장치로부터 들어오는 내용을 파일로 기록하도록 만듭니다. 여기서의 표준 입력 장치는 우리가 PuTTY를 통해서 밀어넣는 키보드 입력이 될 것이므로 간단한 스크립트 작성이 가능해집니다. 스크립트 파일의 내용은 다음과 같습니다.

<?php
phpinfo();
?>
[Ctrl+Z 키 입력] 

33. 기본적인 구성이 완료되었으므로 이제 Windows Azure Management Portal (http://manage.windowsazure.com/)으로 이동하여 방화벽 설정을 조금 변경해야 합니다. 현재 방화벽은 Secure Shell을 위해서 TCP 22번 포트만 개방된 상태이며 Apache HTTP Server가 열어놓은 TCP 80 포트가 밖에서도 연결될 수 있도록 설정을 변경해야 합니다. 아래 그림에서처럼 Endpoints 메뉴를 클릭하고 하단의 Add Endpoint 버튼을 클릭하여 새 설정을 추가합니다.

note. Linux VM 자체의 방화벽 설정이 있더라도 Windows Azure Firewall에서 열지 않으면 외부에서는 특정 포트 번호로 연결을 맺을 수 없습니다. 그러나 여러 VM이 단일 Cloud Service 안에 Join하는 경우 이 영역 안의 각각의 VM들은 상호 간의 자체 방화벽 구성이 Windows Azure 방화벽 구성보다 우선시됩니다.

34. Add Endpoint 라디오 버튼을 체크한 상태에서 다음 버튼을 클릭합니다.

35. NAME에는 알아보기 쉬운 설정 명칭 (여기서는 HTTP로 정했습니다.)을, PROTOCOL은 TCP를, PUBLIC PORT, 즉 밖에서 받아들일 포트 번호는 80, PUBLIC PORT로 받은 연결을 실제로 이어줄 VM 측의 PORT인 PRIVATE PORT도 80으로 지정하여 웹 연결을 개통시킵니다. 설정을 마쳤으면 완료 버튼을 클릭합니다.

36. 설정이 완료될 때 까지 잠시 기다립니다.

37. 정상적으로 반영되면 아래 그림과 같이 녹색 체크 마크가 설정 앞에 나타납니다. 이제 테스트 URL로 접속을 시도합니다. 지금 여러분의 브라우저에서 http://[호스트 이름].cloudapp.net/test.php 와 같이 주소를 입력해봅니다.

38. PHP 5.3 인터프리터가 잘 작동하고 있음을 확인할 수 있습니다. PHP 보완 솔루션도 같이 설치되었다고 나오는데 특이하게도 해외 프로젝트이지만 이름이 SUHOSIN (수호신)이라고 하는군요. :-D

39. Ctrl+F 키를 눌러서 페이지 내 검색 창을 엽니다. 검색 키워드로 CUBRID를 입력하여 아래 그림과 같이 Cubrid Driver가 활성화되어있는지 확인합니다.

40. 이어서 gd를 검색 키워드로 넣었을 때 아래 그림과 같이 항목이 검색되고 GD Support가 enabled로 되어있는지 확인합니다.

41. 이제 드디어 XpressEngine을 설치할 차례입니다. 브라우저 창에서 http://www.xpressengine.com/ 으로 주소를 넣어 이동한 다음, 최신 버전의 XE Core 패키지 다운로드 메뉴를 찾아 클릭합니다.

42. 다운로드 버튼을 오른쪽 버튼으로 클릭하여 바로 가기 복사 메뉴 (혹은 다른 브라우저의 경우 이에 준하는 기능을 활용하세요.)를 클릭하여 다운로드 링크를 가져옵니다. 이 주소를 이용하여 바로 xe.zip 파일을 리눅스 VM에서 내려받으려고 합니다. 이 방법을 사용하지 않고 PuTTY 유틸리티의 자매 도구인 PSFTP 툴을 사용하여 직접 업로드해도 무방하지만 추가 프로그램 없이 손쉽게 접근할 수 있어 이 방법으로 시도하려고 합니다.

43. 리눅스 VM에서 웹의 파일을 콘솔 상에서 다운로드받기 위해 wget 유틸리티를 설치하려고 합니다. 보통은 설치가 이미 되어있지만 업데이트 확인 차 apt-get install wget 명령을 입력하여 다시 설치를 확인합니다.

44. 파일을 다운로드받기 위해서 wget -O xe.zip [42단계에서 복사한 URL] 명령어를 입력합니다. -O 스위치는 HTTP 서버로부터 파일 다운로드가 발생할 때 저장할 파일의 이름을 미리 스위치로 지정한 것입니다. 그리고 42단계에서 복사한 URL은 wget -O xe.zip 명령어 다음에 공백을 한 칸 넣고 콘솔 윈도우에서 마우스 오른쪽 버튼을 클릭하면 아래와 같이 자동으로 붙여넣기가 됩니다. 이제 45단계의 내용을 꼭 참고하세요.

45. 리눅스 Bash 셸의 특성 상 URL에 붙어있는 기호들 중 & (Ampersand) 기호는 꼭 이스케이프 처리를 해주어야 합니다. 키보드의 좌우 방향키를 이용하여 명령어를 수정할 수 있으므로 & 기호를 \& 기호로 아래 그림과 같이 수정해줍니다. 이로서 전체 명령어는 다음과 같습니다.

wget -O xe.zip http://www.xpressengine.com/?module=file\&act=procFileDownload\&file_srl=21367347\&sid=2e7e5518f7168e68513400404840b5f1

46. 정상적으로 아래 그림과 같이 다운로드가 완료되었는지 확인합니다.

47. ZIP 파일의 압축을 풀기 위해서 unzip 유틸리티를 설치해야 합니다. apt-get install unzip 명령을 실행하여 unzip 유틸리티를 설치합니다.

48. unzip xe.zip 명령어를 실행하여 /var/www/xe 디렉터리에 XpressEngine 패키지를 압축 해제하여 설치합니다.

49. 이제 불필요한 파일을 정리하고 퍼미션 설정을 할 차례입니다. /var/www 디렉터리의 xe.zip, test.php 파일을 삭제하고 xe 디렉터리 내에 files 디렉터리를 새로 생성한 다음 chmod 명령어로 디렉터리 퍼미션을 조정합니다.

cd /var/www
rm xe.zip
rm test.php
cd xe
mkdir files
chmod 707 files

50. 이제 브라우저 창에서 http://[호스트 이름].cloudapp.net/xe/ 주소를 넣어 아래 그림과 같이 설치 마법사가 나타나는지 확인합니다.

51. 페이지 언어가 한국어로 변경되었으면 다음 버튼을 클릭합니다.

52. 아래 그림과 같이 모든 사항이 가능으로 표시되면 설치할 준비가 된 것입니다. "설치를 진행합니다." 버튼을 클릭합니다.

53. 이번 강좌에서 데이터베이스로 CUBRID를 사용할 것이므로 데이터베이스 종류는 cubrid를 선택하고 다음 버튼을 클릭하여 진행합니다.

54. 데이터베이스 접속 정보를 설정합니다.

* Apache HTTP Server와 DB 서버가 같은 위치에서 실행 중이므로 loopback 주소인 127.0.0.1을 입력합니다.
* DB 서버에 대해 별도로 포트 번호를 변경하지 않았으므로 포트 번호는 기본값을 사용합니다.
* DB 아이디는 빠른 진행을 위해서 dba로 사용하고, DB 비밀 번호는 28단계에서 지정한 비밀 번호를 입력합니다.
* DB 이름은 25단계에서 지정한 인스턴스 이름인 xe를 입력합니다.
* 테이블 머리말은 기존에 xe를 설치한 적이 없는 DB 위에 설치하는 경우 기본 값을 그대로 사용해도 됩니다.

여기서 참고할 사항은 데이터베이스의 경우 Windows Azure Firewall에서 해당 포트 번호인 33000을 임의로 개방하지 않을 경우 밖에서는 Cubrid 데이터베이스로 접속할 방법이 없습니다. 필요한 경우 Cubrid 서버의 기본 포트 번호를 변경하여 한층 더 강력한 보안을 유지할 수도 있습니다.

55. 데이터베이스 접속이 완료되면 아래와 같이 짧은 주소 사용 여부와 시간대 설정 페이지가 나타납니다. 짧은 주소 모듈이 Apache2 패키지와 함께 설치되므로 체크를 하고, 시간대는 적절하게 선택합니다. 대한민국 사용자들을 대상으로 하는 경우 GMT +09:00 Korea Standard Time, Japan Standard Time 항목을 선택하고 다음 버튼을 클릭합니다.

56. 관리자에 대한 기본적인 정보를 입력합니다. 메일 주소, XE 계정 접속 시 사용할 비밀 번호, 내부 아이디, 닉네임을 빠짐없이 적절하게 모두 입력한 다음 완료 버튼을 클릭합니다.

57. 아래와 같이 Welcome 페이지가 나타나면 설치가 끝난 것입니다. 왼쪽 메뉴들 중 관리 메뉴를 클릭하여 관리자 페이지로 이동합니다. 이 과정에서 다소 시간이 걸릴 수 있습니다.

58. 관리자 페이지가 나타납니다. 설치 환경 수집 동의 팝업에 적절한 응답을 선택합니다.

59. 이제 사이트를 구성할 준비가 완료되었습니다.

60. Azure Virtual Machine 관리자 페이지로 되돌아와서 보면 가상 컴퓨터의 움직임이 그래프로 기록된 것을 볼 수 있습니다. 이제 이 그래프가 점점 활기차고 높게 그려질 것을 기대해도 되겠군요. :-)

마무리하기

지난번에는 Windows Azure Web Site에서 XpressEngine을 설치하는 과정을 설명드렸습니다. 여기서는 MySQL의 클라우드 버전인 ClearDB의 서비스를 사용하는 것을 예로 들어드렸습니다. 이 방법을 사용하시면 동시 접속자 수가 많은 웹 사이트에서 최고의 확장성을 목표로 운영할 수 있습니다. 오늘 소개해드린 방법은 일반적인 서버 호스팅 환경에 익숙하신 분들께 더 친숙하고 유익한 방법이 될 수 있습니다. 늘 그렇지만, 비용과 목적에 알맞는 적절한 서비스 구성이 최적의 클라우드 서비스 선택이 될 것입니다.

감사합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

기술 소식2012. 11. 1. 23:14

안녕하세요. Windows Azure MVP 남정현입니다. 이번 BUILD 2012에서는 Windows 8과 Windows Server 2012를 필두로 하는 다양한 업데이트 소식이 있었는데요, 한 번에 알아보기 쉽도록, 그리고 약간의 시차를 두고 있는 흥미로운 새 소식들도 같이 전해드릴까 합니다.

Windows Server 2012 및 .NET Framework 4.5 지원 추가

Visual Studio 2012 출시와 함께 Windows Server 2012, .NET Framework 4.5에 대한 지원이 새로 추가되었습니다. 그리고 ASP.NET의 경우 ASP.NET MVC 4.0 업데이트를 포함하고 있고, C# 5.0 및 VB 11.0에 대한 지원도 포함하여 멀티 스레드 프로그래밍을 좀 더 생산성있게 할 수 있는 방안을 대폭 마련하고 있습니다. .NET Framework 4.5에서 향상된 내용들은 http://msdn.microsoft.com/ko-kr/library/ms171868.aspx 에서 확인하실 수 있습니다.

Windows Azure Mobile Service의 Windows Phone 8 지원 추가

Windows Phone 8 SDK 발표와 함께 Windows Azure Mobile Service에서 Windows Phone 8 대상 SDK도 같이 발표하였습니다. Windows 8과 Windows Phone 8을 위한 App 모두를 지원하는 것이므로 N 스크린 앱 개발에 큰 도움이 될 것입니다. 자세한 튜토리얼은 https://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started-wp8/ 에서 확인하실 수 있습니다.

Windows Azure Store 런칭

Windows Azure 2012년 초반 업데이트에 공개된 적이 있었던 ClearDB의 Azure 기반 MySQL 데이터베이스 서비스는 이미 잘 알려져 있습니다. 그런데 한 가지 아쉬웠던 점이 있었다면 무료 서비스에 한정되어있었던데다 Windows Azure와는 따로 떨어져있는, 접근성이 그다지 좋지 않은 부가 서비스였었습니다. 그러나 이제는 ClearDB의 사례를 포함하여 Windows Azure 서비스에 결합할 수 있는 다양한 컴패니언 서비스 및 데이터 소스를 한 곳에서 쉽게 구매하고 자원으로 관리할 수 있도록 Windows Azure Store 안에서 통합 관리할 수 있게 되었습니다. 아쉽게도 2012년 11월 현재 미국에서만 런칭이 된 상태입니다만 조만간 한국에서도 편리하게 대량 E-MAIL 발송, 대용량 MySQL 데이터베이스 등 다양한 서비스를 쉽게 구매해서 실제 클라우드 서비스에 반영할 수 있을 것입니다. 자세한 내용은 https://www.windowsazure.com/en-us/store/overview/ 에서 살펴보실 수 있습니다.

새 버전의 .NET용 Windows Azure SDK 및 가이드 런칭

.NET용 Windows Azure SDK의 새 버전이 발표되었습니다. 다른 써드파티의 Windows Azure 관련 도구와 비슷하게 동작하도록 개선되고 향상된 Visual Studio Add-in을 대거 포함하며, 새롭게 설계된 클래스 라이브러리 및 .NET Framework 4.5 타겟팅을 지원합니다. 자세한 내용은 http://msdn.microsoft.com/en-us/library/ff683673.aspx#BK_October2012 에서 확인하실 수 있습니다.

Windows Azure 분산 캐시 정식 업데이트

AppFabric Cache로 소개되었던 적이 있는 이전 버전의 캐시는 매우 가격이 비쌌고 이에 비해 얻을 수 있는 득이 그렇게 크지 않았었습니다. 이를 대체하여 좀 더 사용자에게 실질적인 캐시 서비스의 이점을 누릴 수 있게 하기 위하여 새롭게 분산 캐시를 업데이트하였는데, 이번 릴리즈에서 정식 서비스로 업데이트되었습니다. Web Role이나 Worker Role, 혹은 Cache 전용 Worker Role을 만들어서 상황에 따라 유동적으로 증감하는 고성능 분산 캐시를 쉽게 구축할 수 있게 되었습니다. 이에 대한 자세한 내용은 https://www.windowsazure.com/en-us/home/features/caching/ 에서 살펴보실 수 있습니다.

Visual Studio Team Foundation Service Online 정식 런칭

Visual Studio TFS Online 또한 정식으로 서비스가 런칭되었습니다. 2012년 11월 현재 무료 버전으로만 서비스가 운영되고 5명의 사용자까지 지원합니다. Visual Studio, Eclipse, XCode와 함께 연동할 수 있도록 다양한 애드인과 함께 배포되며, Windows Azure Web Site 서비스와 함께 연동할 수 있으므로 다양한 요구 사항을 충족할 수 있습니다. 그리고 Git을 이용하여 TFS를 대상으로 작업할 수 있는 도구인 Git-TF (코드프로젝트 홈페이지: http://gittf.codeplex.com/, Microsoft 다운로드 페이지 주소: http://www.microsoft.com/en-us/download/details.aspx?id=30474)도 같이 활용하시면 유용하실 것입니다. http://blogs.msdn.com/b/somasegar/archive/2012/10/31/team-foundation-service-is-released.aspx 에서 자세한 내용을 보실 수 있으며, 서비스 사용은 http://tfs.visualstudio.com/ 에서 신청 가능합니다.

Windows Azure SQL Data Sync 10월 업데이트

오랜 기간에 걸쳐서 평가를 진행 중인 Windows Azure SQL Data Sync 서비스가 이번 10월 업데이트를 기준으로 전세계 모든 데이터센터에서 사용 가능하도록 배포가 완료되었습니다. Windows Azure SQL Data Sync 서비스를 사용하면 기존 SQL 서버 데이터베이스 간, Windows Azure SQL Database 간, 혹은 기존 SQL 데이터베이스와 Windows Azure SQL Database 사이의 데이터 동기화를 비동기적으로 최소한의 코드 작성을 통하여 손쉽게 수행할 수 있는 것이 특징이며 이에 대한 자세한 내용이 문서화되어있습니다. SQL Data Sync 서비스에 대한 소개는 http://msdn.microsoft.com/ko-kr/library/hh456371 페이지를, SQL Data Sync 서비스에 대한 시행착오를 최소화하기 위한 가이드는 http://msdn.microsoft.com/ko-kr/library/hh667328.aspx 페이지의 내용을 참고하시면 유용합니다.

Windows Azure 기술 운영에 관한 중국의 21Vianet社와의 MOU 체결

Windows Azure는 Public Cloud Computing Service로, 그동안 중국 내에서는 해외 데이터센터의 이용이 쉽지 않았던 비즈니스 상의 특성 때문에 Windows Azure가 서비스를 할 수 없었던 대표적인 국가였습니다. 이러한 한계를 극복하기 위해서 21Vianet社 (http://www.en.21vianet.com/)와의 MOU를 체결하여 Windows Azure 운영 시스템을 중국 내 로컬 데이터센터에서 이용할 수 있도록 협약을 맺었다는 소식이 Windows Azure 공식 블로그를 통해서 공개되었습니다. ( http://blogs.msdn.com/b/windowsazure/archive/2012/11/01/cloud-os-is-coming-to-china.aspx) 중국 내에서 클라우드 컴퓨팅 서비스를 도입할 것을 계획 중이신 경우 향후 21Vianet을 통하여 Windows Azure와 유사한 서비스를 중국 내 로컬 데이터센터를 이용하여 경험할 수 있을 것입니다.


Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2012. 9. 15. 20:37

안녕하세요. Windows Azure MVP 남정현입니다. 오늘은 Visual Studio 2012 출시와 더불어서 Express Edition의 업그레이드에 대한 이야기를 전해드리려고 합니다.

개인적으로 매우 좋아하고 아끼는 Visual Studio 제품 라인 업 중에 Express Edition이 있습니다. 무료로 제공되는 개발 도구임에도 기능에서나 활용 면에서 부족함이 전혀 없고, 제 스스로에게 있어서 작업 시간을 줄여주고 시행 착오를 최소화하는데에 지대한 공헌을 하는 멋진 개발 툴입니다.

이번 2012 라인 업에서는 아래와 같이 구성이 변경되었습니다.

  • Visual Studio 2012 Express for Web: 기존의 Visual Web Developer 2010을 이어서 업그레이드된 버전으로 ASP.NET 4.5와 Windows Azure 최신 개발 툴킷, Silverlight 개발 환경등을 포함하고 있습니다.
  • Visual Studio 2012 Express for Desktop: 기존의 Visual C# Express 2010, Visual Basic .NET Express 2010, Visual C++ Express 2010을 통합하여 데스크탑 응용프로그램 개발에 최적화된 버전으로 업그레이드되었습니다.
  • Visual Studio 2012 Express for Windows 8: Windows 8에서 새로 추가된 Windows Store 앱을 만들기 위하여 필요한 개발 도구로 동시에 Expression Blend for Windows 8이 같이 설치됩니다.
  • Visual Studio Team Foundation Server 2012 Express: 고가의 상용 버전 제품으로만 알려져있었던 Team Foundation Server도 Express 버전을 새로 출시하게 되었습니다. 소규모 개발 팀을 운영 중인 경우 한 번즈음 고려해볼 수 있는 형상 관리, 작업 관리, 빌드 자동화를 제공합니다.

언어 별로 나누어져 있었기 때문에 장점이자 단점으로 동시에 작용하던 작고 가벼움은 아쉽게도 더 이상 존재하지는 않습니다. 그렇지만 Express Edition 특유의 한계를 극복하고 더 강력한 기능을 더하고 단순히 학습용이 아닌 소규모 개발 팀을 위한 배려를 모두 포함하고 있다는 것은 매우 기쁜 일입니다.

그리고 실제로 Visual Studio 2012 전체 버전을 구입하시기 전에 제품의 표면적인 기능만을 제한된 시간 내에 평가해야 하는 트라이얼 버전 대신, 실제 업무에도 자연스럽게 반영해볼 수 있는 Express Edition을 통해서 충분한 시간을 가지면서 활용하시면 좀 더 좋은 부분을 많이 보실 수 있을 것이라고 기대합니다.

Web과 Desktop 버전은 Windows 운영 체제 버전과 관계없이 사용이 가능하며, Windows 8 버전의 경우에는 실제로 Windows 8 운영 체제 위에서 실행되어야만 개발 환경 구축이 가능합니다. 그리고 이전과 마찬가지로, 무료로 사용이 가능하고 상용으로도 활용이 가능하지만 설치 후 기간 내에 Microsoft 등록 페이지에 가서 제품에 대한 25자리 등록 번호를 받아서 등록해야 하는 절차는 변함 없습니다.

2012 Express Edition과 2010 Express Edition을 다운로드하시려면 http://www.microsoft.com/visualstudio/kor/downloads 페이지로 가시면 됩니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. 현재 네이버 메인에 나오고 있습니다.

    2013.01.28 15:38 신고 [ ADDR : EDIT/ DEL : REPLY ]

PaaS2012. 8. 6. 08:00

지난번 글에 이어서 Access Control을 실제 ASP.NET 응용프로그램에 연동하는 방법을 살펴보도록 하겠습니다. Access Control을 연동하기 위해서는 .NET의 경우 Windows Identity Foundation이라는 새로운 기술을 필요로 합니다. Windows Identity Foundation은 여러 버전의 런타임으로 나누어져 있으며, Windows Server 2003부터 Windows Server 2012까지 지원되지만, 보통은 Windows Server 2008 이후의 OS를 사용하는 것이 구성이나 배포가 단순합니다.

이 글에서는 Visual Studio 2010과 WIF 3.5를 사용하는 것을 기준으로 가이드를 쓰려고 합니다. 역시 나중에 기회가 되면 Visual Studio 2012와 WIF 4.5기준의 업데이트를 한 번 더 소개하겠습니다.

글에 있는 내용을 따라서 시작하기 전에 ACS를 이용하는 웹 사이트를 배포할 서버와 개발자 컴퓨터에 다음의 런타임을 버전에 맞추어 선택적으로 미리 설치하여 구성하셔야 합니다.

운영 체제 버전 별 런타임 설치하기

개발 도구 (SDK) 설치하기

개발 도구의 경우 한국 Microsoft 홈페이지에는 3.5 버전의 SDK만 게시되어있는데, .NET Framework 3.5가 아닌 4.0을 타겟으로 하는 경우에는 영어 홈페이지로 이동해서 직접 다운로드해야 합니다. 아래는 패키지 파일 다운로드 경로를 직접 걸어놓은 것으로 필요한 패키지를 골라 설치하면 됩니다.

SDK 또한 Windows Server 2003 SP2 부터 설치가 가능합니다.

Windows 8 및 Windows Server 2012에서 WIF 3.5 런타임 설치하기

Windows Identity Foundation 4.5 대신 3.5 버전을 사용해야 할 경우 아래 절차를 거쳐 설치할 수 있습니다.

제어판의 프로그램 및 기능 - 또는 - 프로그램 빠른 검색이나 Windows + R 단축키로 사용 가능한 실행 대화 상자에서 appwiz.cpl 제어판 애플릿을 시작합니다.

그 다음 Windows 기능 켜기/끄기 마법사를 시작합니다.

여러 항목들 중에서 Windows Identity Foundation 3.5 항목을 체크하고 확인 버튼을 클릭합니다.

잠시 기다리면 아래와 같이 완료 대화 상자가 나타납니다.

이제 여기에 WIF SDK 3.5 - 또는 - 4.0 버전을 설치하면 됩니다.

Visual Studio 2008 및 Visual Studio 2010의 경우 - FEDUTIL.EXE 사용하기

런타임의 경우 Windows Identity Foundation의 실행을 위한 클래스 라이브러리 및 네이티브 구성 요소들을 배포하기 위한 목적으로 사용하는 것이고, 기존에 만든 응용프로그램의 환경 설정 파일을 변경하거나 클래스 라이브러리 도움말 등을 포함하는 것이 SDK의 구성입니다. 그리고 부가적으로 SDK의 경우에는 Visual Studio와 연동하는 기능도 제공합니다만 이 기능은 제대로 설치가 될 수도 있고 그렇지 않을 수도 있어서 신경쓸 필요는 없는 부분입니다. SDK에서 진짜 중요한 부분은 FEDUTIL.EXE 라는 마법사형 프로그램으로 이 프로그램을 사용하여 여러분의 asp.net 응용프로그램을 WIF, ACS와 연결시킬 때 필요한 복잡한 설정을 자동화할 수 있습니다.

시스템 사용 환경에 따라 FedUtil.exe 파일의 설치 위치에 다소 차이가 있지만 아래와 같이 요약할 수 있습니다.

  • 32비트 버전 설치 시: %programfiles%\Windows Identity Foundation SDK\v4.0\FedUtil.exe
  • 64비트 버전 설치 시: %programfiles(x86)%\Windows Identity Foundation SDK\v4.0\FedUtil.exe

FedUtil.exe 프로그램을 실행시키고 잠시 기다리면 아래와 같이 마법사가 시작됩니다.

UI 언어는 환경에 따라 한국어가 나올 수도, 영어가 나올 수도 있습니다. 응용프로그램 설정 파일의 위치를 묻는 부분에는 여러분이 WIF를 적용하려는 ASP.NET 웹 프로젝트의 기본 web.config 파일 경로를 지정하는 곳이며, Visual Studio로 해당 프로젝트를 편집 중에 있더라도 안전하게 적용할 수 있습니다.

노트: Visual Studio와 연동된다는 것은 이 유틸리티를 프로젝트 실행 도중 즉시 호출할 수 있도록 "STS 추가 마법사"라는 이름으로 솔루션 탐색기 컨텍스트 메뉴에 추가하는 정도의 편의 제공이기 때문에 이 유틸리티를 직접 호출해도 무방합니다.

그리고 Application URI에는 지난번 글에서 소개했던 것과 같이 Ad-hoc 서버의 포트 번호를 확인하여 얻을 수 있는 localhost 주소를 이곳에 기재해야 합니다. 프로덕션 환경에서 적용하려면 당연히 이 부분이 실제 프로덕션 웹 사이트의 주소가 되어야 합니다.

Application URI에 HTTPS대신 HTTP 주소를 지정할 경우 아래와 같은 경고 메시지가 나타나지만, Access Control 테스트를 위한 것이므로 지금은 무시하고 넘어갑니다.

계속 진행하면 보안 토큰 서비스의 주소를 물어보는 단계가 나타납니다. 이 단계에서 실제로 Azure Access Control Service의 웹 서비스 주소를 지정하여 WIF와 ACS간에 연동을 이루게 됩니다.

여기에 어떤 주소를 넣어야 할까요? 다시 Azure Access Control 관리자 웹 서비스로 되돌아가봅니다. 관리자 웹 서비스 페이지 좌측 제일 하단의 응용프로그램 통합 링크를 클릭하면 페이지 하단에 STS 서비스를 위한 WS-Federation Metadata Endpoint URL이 보이는데 이 주소를 그대로 Copy & Paste합니다.

다음 단계로 진행하면 ACS 서비스가 제시한 인증서가 올바른 인증서가 아니라는 오류를 표시합니다. 이전에 언급한대로 Azure ACS가 프로덕션 환경에서 제대로 작동하려면 정식 서버 인증서를 필요로 합니다. 여기서는 마법사가 기본으로 제안하는 인증서 체인 검사 비활성화를 선택하고 진행하겠습니다.

토큰 암호화에 대한 설정을 지정하는 페이지가 나타납니다. ACS 설정에서 토큰 암호화에 대한 부분을 구성하였다면 이 단계에서도 호환 가능한 설정을 같이 지정해야 합니다.

웹 서비스가 던져줄 수 있는 클레임의 종류에 대한 설명이 열거됩니다. 다음 버튼을 클릭합니다.

이제 마침 버튼을 눌러 web.config 파일을 업데이트합니다.

별다른 이상이 없다면 아래와 같이 성공 메시지 상자가 나타나고 FedUtil.exe 프로그램이 종료될 것입니다.

NOTE: Visual Studio를 실행 중이었다면 web.config 파일을 열어둔 상태였을 경우 파일이 변경되었음을 감지하고 다시 읽어들일 것인지 물어볼 수 있습니다. 이 경우 꼭 바뀐 파일 내용을 다시 읽도록 해주어야 하며, 편집기 버퍼에 남아있는 컨텐츠를 저장하면 FedUtil.exe로 변경한 내용이 소실되므로 유의해야 합니다. 편집기 버퍼에서 바꾼 내용이 FedUtil.exe 실행 전에 많이 존재한다면 변경된 web.config 파일을 별도로 백업받아놓고 두 파일을 적절하게 병합해야 합니다.

변경된 web.config 파일 내용 살펴보기

이제 FedUtil.exe 프로그램에서 어떤 일을 해주었는지 살펴볼 차례입니다. 우선 여러분의 웹 프로젝트 디렉터리에 새로운 디렉터리와 파일들이 나타나는데, 아래와 같습니다. 

FederationMetadata 폴더에 ACS 서비스와 상호대조를 위한, ACS로부터 복제한 메타데이터 파일이 들어있습니다. 실제 서비스가 제대로 작동하기 위해서는 이 파일이 개발자 환경이나 프로덕션 서버로 정확하게 배포되어야 합니다. 버전 관리 시스템을 사용하는 경우 이 파일이 버전 관리 대상에 포함될 수 있도록 해야 합니다.

그리고 web.config 파일이 변경된 것과 더불어 이전 파일에 대한 백업도 들어있습니다. 백업 파일은 확인 후 필요없으면 삭제해도 무방합니다.

그렇다면 web.config 파일은 어떻게 바뀌었는지 한 번 살펴보도록 할까요?우선 파일을 열었을 때 가장 먼저 눈에 띄는 것은 새로운 Configuration Handler를 추가한 부분인데, 아래와 같습니다.

  <configSections>
    <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>

새로운 Configuration Handler를 지정하고 있으므로 설정 파일 어딘가에 새로운 설정 섹션이 하나 더 추가되어있겠군요. 그리고 appSettings 태그 아래에는 메타데이터 원본 경로에 대한 설정이 들어있습니다.

  <appSettings>
...
    <add key="FederationMetadataLocation" value=https://<네임스페이스>.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml />
...
  </appSettings>

그리고 직전에 살펴본 FederationMetadata 폴더를 위한 특권이 하나 들어있습니다. 인증 세션을 거치지 않았어도 누구나 FederationMetadata 폴더는 접근할 수 있도록 열어놓았군요.

  <location path="FederationMetadata">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>

반면에 웹 응용프로그램의 모든 영역에 대해서는 보호가 걸리게 됩니다.

  <system.web>
...
    <authorization>
      <deny users="?" />
    </authorization>
    <authentication mode="None" />
...
    <!--Commented out by FedUtil-->
    <!--<authentication mode="Forms"><forms loginUrl="~/Account/LogOn" timeout="2880" /></authentication>-->
  </system.web>

달리 표현하면 web.config이 관할하는 모든 영역에 대해서는 ACS를 통한 로그인을 거치지 않을 경우 자동으로 ACS측 로그인 페이지로 리디렉션됨을 의미합니다. 이 부분에 대한 조율이 필요하다면 ASP.NET MVC의 경우 영역으로 별도 영역을 파티셔닝하거나, Location 태그를 적극 활용해야 합니다. 그리고 중요한 차이점이 하나 더 보이는데 WIF의 인증 체계는 기존의 ASP.NET이 제공하던 Form 인증, AD 인증, Windows 인증 및 Passport 인증 어디에도 속하지 않는다는 것입니다.

그리고 당연한 이야기이지만 어셈블리 참조가 걸려있습니다. web.config 파일 및 동적 컴파일 호출 시 유효한 대상으로 걸려있는 것이고, Visual Studio 프로젝트나 별도 컴파일 호출 시 WIF를 사용하려면 프로젝트 참조에서 Microsoft.IdentityModel 어셈블리를 직접 추가해야 합니다.

  <system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
...
        <add assembly="Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
...
      </assemblies>
    </compilation>
...
  </system.web>

ASP.NET 차원에서는 마지막으로 HTTP 모듈이 대체되는 부분이 있습니다. WIF가 기존 ASP.NET 인증 체계를 완전히 재정의해야 하므로 아래의 모듈이 새로 추가됩니다.

    <httpModules>
      <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </httpModules>

같은 설정이지만 IIS 7 이후의 서버들을 위해서는 <system.webServer> 태그 설정도 동일하게 추가됩니다.

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
      <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
    </modules>
  </system.webServer>

이제 끝으로 제일 서두에 언급된 새로운 설정 핸들러가 web.config 끝자락에 보입니다.

  <microsoft.identityModel>
    <service>
      <audienceUris>
        <add value="http://localhost:50086/" />
      </audienceUris>
      <federatedAuthentication>
        <wsFederation passiveRedirectEnabled="true" issuer="https://rkttuacs.accesscontrol.windows.net/v2/wsfederation" realm="http://localhost:50086/ " requireHttps="false" />
        <cookieHandler requireSsl="false" />

      </federatedAuthentication>
      <applicationService>
        <claimTypeRequired>
          <!--Following are the claims offered by STS 'https://rkttuacs.accesscontrol.windows.net/'. Add or uncomment claims that you require by your application and then update the federation metadata of this application.-->
          <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="true" />
          <claimType type="
http://schemas.microsoft.com/ws/2008/06/identity/claims/role" optional="true" />
          <!--<claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" optional="true" />-->
          <!--<claimType type="
http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider" optional="true" />-->
        </claimTypeRequired>
      </applicationService>
      <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
        <trustedIssuers>
          <add thumbprint="CE5BF1CE19528FEDA7FA9F3ECF87A85E3B1B6AED" name="https://rkttuacs.accesscontrol.windows.net/" />
        </trustedIssuers>
      </issuerNameRegistry>
      <certificateValidation certificateValidationMode="None" />
    </service>
  </microsoft.identityModel>

위의 내용들 가운데에서 굵게 강조 표시한 항목들이 변경의 여지가 있고 제어가 가능한 부분들입니다. 지금으로서는 테스트를 목적으로 하는 것이므로 따로 변경할 것은 없겠습니다.

잘 작동할까요?

워낙에 중요하고 어려운 부분들만 수정해놓은 것이라 불안하게 보입니다. 잘 작동할까요? 한 번 실행해보겠습니다. 

설정 파일에서 변경한대로 사이트에 접속하자마자 ACS 로그인 페이지로 이동합니다. 이후에 다시 살펴보겠지만 이 페이지의 디자인은 얼마든지 재정의 가능합니다. 여기서 Google ID를 시험삼아 로그인에 사용하도록 해보겠습니다.

로그인을 거치고나니 이런 오류 메시지가 나타납니다. 이 문제를 어떻게 해결해야 할까요?

WIF 3.5의 호환성 문제 해결하기

전통적인 로그인 및 사용자 인증 모델에서는 고려할 수 없었던 동작을 수행해야 하는데 안타깝게도 ASP.NET은 이러한 부분에 대해서 다소 부정적인 면모를 보입니다. 이 문제를 해결하는 방법 자체는 단순합니다. 입력 폼으로 들어오는 XML 데이터를 무시하도록 설정을 완화시키면 가능합니다. 그렇지만 그냥 그렇게 프로덕션 환경에 설정을 풀어놓은채로 올리기에는 너무 안일합니다. 뭔가 좋은 방법이 없을까요?

유효성 검사를 풀지 않으면서도 안전하게 WIF와 ACS 사이의 통신을 인정할 수 있는 방법으로 Custom Validation Handler를 추가하는 방법이 있습니다. 이 코드는 아래의 웹 페이지의 코드를 인용한 것입니다.

http://social.technet.microsoft.com/wiki/contents/articles/1725.windows-identity-foundation-wif-a-potentially-dangerous-request-form-value-was-detected-from-the-client-wresult-t-requestsecurityto.aspx

C# 소스 코드

//-----------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
//-----------------------------------------------------------------------------

using System;
using System.Collections.Specialized;
using System.Web;
using System.Web.Helpers;
using System.Web.Util;
using Microsoft.IdentityModel.Protocols.WSFederation;

/// <summary>
/// This SampleRequestValidator validates the wresult parameter of the
/// WS-Federation passive protocol by checking for a SignInResponse message
/// in the form post. The SignInResponse message contents are verified later by
/// the WSFederationPassiveAuthenticationModule or the WIF signin controls.
/// </summary>
public class SampleRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString(
        HttpContext context, string value, RequestValidationSource requestValidationSource,
        string collectionKey, out int validationFailureIndex)
    {
        validationFailureIndex = 0;

        if (requestValidationSource == RequestValidationSource.Form &&
            !String.IsNullOrEmpty(collectionKey) &&
            collectionKey.Equals(WSFederationConstants.Parameters.Result, StringComparison.Ordinal))
        {
            NameValueCollection unvalidatedFormValues = Validation.Unvalidated(context.Request).Form;
            SignInResponseMessage message = WSFederationMessage.CreateFromNameValueCollection(
                WSFederationMessage.GetBaseUrl(context.Request.Url),
                unvalidatedFormValues) as SignInResponseMessage;

            if (message != null)
                return true;
        }

        return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
    }
}

Visual Basic .NET 코드

'-----------------------------------------------------------------------------
'
' THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF
' ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
' THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
' PARTICULAR PURPOSE.
'
' Copyright (c) Microsoft Corporation. All rights reserved.
'
'
'-----------------------------------------------------------------------------

Imports System
Imports System.Collections.Specialized
Imports System.Web
Imports System.Web.Helpers
Imports System.Web.Util
Imports Microsoft.IdentityModel.Protocols.WSFederation

''' <summary>
''' This SampleRequestValidator validates the wresult parameter of the
''' WS-Federation passive protocol by checking for a SignInResponse message
''' in the form post. The SignInResponse message contents are verified later by
''' the WSFederationPassiveAuthenticationModule or the WIF signin controls.
''' </summary>
Public Class SampleRequestValidator
    Inherits RequestValidator

    Protected Overrides Function IsValidRequestString( _
        context As HttpContext, value As String, requestValidationSource As RequestValidationSource, _
        collectionKey As String, ByRef validationFailureIndex As Integer) As Boolean

        validationFailureIndex = 0

        If requestValidationSource = Util.RequestValidationSource.Form AndAlso _
            String.IsNullOrEmpty(collectionKey) = False AndAlso _
            collectionKey.Equals(WSFederationConstants.Parameters.Result, StringComparison.Ordinal) Then

            Dim unvalidatedFormValues As NameValueCollection = Validation.Unvalidated(context.Request).Form
            Dim message As SignInResponseMessage = TryCast(WSFederationMessage.CreateFromNameValueCollection( _
                WSFederationMessage.GetBaseUrl(context.Request.Url), _
                unvalidatedFormValues), SignInResponseMessage)

            If message IsNot Nothing Then
                Return True
            End If
        End If
        Return MyBase.IsValidRequestString(context, value, requestValidationSource, collectionKey, validationFailureIndex)
    End Function
End Class

위의 코드가 이상 없이 컴파일이 잘 되는지 프로젝트에 클래스를 새로 하나 추가하여 확인하고, web.config으로 이동하여 아래와 같이 설정을 수정합니다.

C#의 경우

<system.web>
  ...
  <httpRuntime requestValidationType="SampleRequestValidator" />
  ...
</system.web>

VB.NET의 경우

<system.web>
  ...
  <httpRuntime requestValidationType="[프로젝트 이름].SampleRequestValidator" />
  ...
</system.web>

VB.NET의 경우 네임스페이스의 경로가 상대성을 가지기 때문에 정확한 것은 개체 탐색기 등을 이용하여 확인해보는 것이 필요합니다. 대개는 위와 같이 기술했을 때 문제가 없습니다.

이제 다시 로그인을 시도하면 아래 그림과 같이 인증이 통과되는 것을 볼 수 있습니다. 

한 가지 더 - 로드 밸런싱에 대응하기

아직 모든 것이 완벽하게 마무리 되지 않았는데, 로드 밸런싱에 대한 부분이 해결되지 않았습니다. 기본적으로 ASP.NET과 마찬가지로 컴퓨터 상태에 의존하여 난수를 생성하는 DPAPI (Data Protection API)를 기반으로 하므로 로드 밸런싱 환경에서는 아래와 같은 유형의 오류 메시지가 나타납니다.

Key not valid for use in specified state

위의 오류를 해결하기 위해서는 DPAPI 기반의 암호화 대신 로드 밸런싱이나 웹 팜에 참여하는 노드들 간의 키를 일치시켜야 합니다. Global.asax 파일이 없을 경우 하나 추가하여 Application_Start 메서드 혹은 이벤트 처리기에 아래의 코드 조각을 추가합니다.

C# 코드

FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated;

VB.NET 코드

AddHandler FederatedAuthentication.ServiceConfigurationCreated, OnServiceConfigurationCreated()

이어서 추가된 이벤트 처리기의 코드 내용을 아래와 같이 프로그래밍합니다.

C# 코드

using System.Collections.Generic;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Web;
using Microsoft.IdentityModel.Web.Configuration;
...
    private void OnServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e)
    {
       List<CookieTransform> sessionTransforms = new List<CookieTransform>(
           new CookieTransform[] {
               new DeflateCookieTransform(),
               new RsaEncryptionCookieTransform(e.ServiceConfiguration.ServiceCertificate),
               new RsaSignatureCookieTransform(e.ServiceConfiguration.ServiceCertificate) 
           });
       SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(
          sessionTransforms.AsReadOnly());
       e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);
    }

VB.NET 코드

Imports System.Collections.Generic
Imports Microsoft.IdentityModel.Tokens
Imports Microsoft.IdentityModel.Web
Imports Microsoft.IdentityModel.Web.Configuration
...
    Private Sub OnServiceConfigurationCreated(sender As Object, e As ServiceConfigurationCreatedEventArgs)
        Dim sessionTransforms As New List(Of CookieTransform)(New CookieTransform() { _
            New DeflateCookieTransform(), _
            New RsaEncryptionCookieTransform(e.ServiceConfiguration.ServiceCertificate), _
            New RsaSignatureCookieTransform(e.ServiceConfiguration.ServiceCertificate)
            })
        Dim sessionHandler As New SessionSecurityTokenHandler( _
            sessionTransforms.AsReadOnly)
        e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace( _
            sessionHandler)
    End Sub

마지막으로 Azure Cloud Service나 VM, 혹은 여러분의 웹 팜 환경에서 실행되는 컴퓨터에 동일한 인증서를 사용하도록 배포하면 로드밸런싱 환경에서도 안전하게 ACS 기반 인증을 처리할 수 있게 됩니다.

좀 더 많은 자료들과 글 작성에 도움이 된 자료들

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

IaaS2012. 8. 2. 10:19

안녕하세요. Windows Azure MVP 남정현입니다. 오늘은 Windows Azure 관리자 포탈에 대해서 한 가지 이야기를 드릴까 합니다. 현재 Windows Azure는 Preview 버전의 포탈과 Retail 버전의 포탈로 나누어서 서비스가 제공되는 상황인데, 그렇다보니 어디를 어떻게 들어가서 이용해야 하는지 햇갈릴만큼 다소 복잡한 상태입니다.

일단 두 포탈 사이에 가장 큰 기술적 차이는, Retail 버전의 경우 Silverlight로 서비스를 제공하는 것이고 접속 주소는 windows.azure.com 입니다. 그리고 Preview 버전은 HTML5로 서비스를 제공하는 것이며 manage.windowsazure.com이 접속 주소입니다. 양쪽 사이트의 모습은 아래 그림과 같이 차이가 납니다.

Retail 버전의 관리자 포탈 (windows.azure.com으로 접속)

Preview 버전의 관리자 포탈 (manage.windowsazure.com으로 접속) 

Preview Portal의 경우 계속해서 기능을 개발 중에 있으며, Azure Web Site, Azure Virtual Machine, Azure Media Service에 대한 관리 및 프로비져닝 기능을 제공합니다. 반면 Service Bus나 Access Control과 같은 Cloud Service와 연계되는 고급 Building Block 서비스들은 Preview Portal 아닌 Retail Portal로 가서 프로비져닝하거나 관리해야 합니다. 이후에는 모든 서비스들이 새 포탈쪽으로 제공이 될 예정에 있습니다.

만약 실무에서 SLA 계약을 지켜줄 수 있는 서비스들로만 안전하게 Windows Azure를 사용하기 원하신다면, Preview Portal을 통해서 상품을 프로비져닝하지는 마시고, 새 업데이트 소식이 나오기 전까지는 windows.azure.com에서만 서비스를 사용하시는 것이 정확합니다. 포탈을 포함하여 Azure Web Site, Azure Virtual Machine, Azure Media Service, Azure Virtual Network는 모두 Preview 상품이기 때문에 아직 완전한 상태는 아닙니다.

이 외에도 SQL Database (구 SQL Azure), Access Control 또한 자체 포탈을 현재는 별도로 운영을 하고 있으므로 세부적인 설정은 메인 관리 포탈을 통해서 접근하고 관리할 수 있으므로 참고하시면 도움이 될 것입니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2012. 7. 13. 18:07

안녕하세요. Windows Azure MVP 남정현입니다.

이전에 신청한적이 있었던 Windows Azure Media Service Preview 프로그램에 대한 테스트 계정을 오늘 얻을 수 있었습니다. 이에 맞추어 간단한 기능을 테스트해보고 처음으로 블로그 포스트를 남겨봅니다. Windows Azure Media Service는 Windows Azure Platform에 근래에 새로 추가된 클라우스 서비스의 한 종류로, 여러분이 가지고 있는 동영상 컨텐츠를 클라우드 컴퓨팅 상의 자원을 활용하여 인코딩하고 그 내용을 곧바로 저장소와 CDN에 게시할 수 있도록 도와주는 서비스입니다. 현재는 프리뷰 버전으로 나온 상태이므로 기능이나 API에 많은 변동이 있을 수 있습니다. 그러나 서비스의 기본 방향이나 목적은 지금 설명 드린 내용이 주된 내용이 되므로 국내외에서 미디어 관련 서비스를 활용하고자 하는 많은 고객들의 관심을 얻을 수 있을 것으로 봅니다.

Windows Azure Media Service를 신청하려면?

Windows Azure Media Service는 현재 신청을 별도로 받아서 계정을 할당하는 방식으로 사용해 볼 수 있습니다. 이를 위해서는 우선 Windows Azure 계정을 하나 만드셔야 하며, http://www.windowsazure.com/ 에서 신청하실 수 있습니다. 국내에 서비스가 정식으로 시작되었기 때문에, 이제는 해외 거주지 정보가 필요하지 않고 쉽게 신청을 마무리하실 수 있습니다.

Windows Azure 계정 관리 홈페이지 (account.windowsazure.com)에 접속하신 후에, "미리 보기 기능"을 클릭하면 현재 신청 가능한 프리뷰 프로그램들이 열거됩니다. 이 중에서 Media Services 항목을 신청하시면 대기열에 예약이 됩니다. 승인이 완료되면 아래 그림과 같이 관리 홈페이지 (manage.windowsazure.com)에 접속하였을 때 Media Service에 대한 메뉴가 새로 나타납니다.

 

미디어 서비스를 만든 후에는 새로운 미디어 서비스를 신청해야 하며, 이 때 미디어 서비스와 연결할 스토리지 계정을 하나 지정하게 됩니다. 미디어 서비스 API로 동영상을 업로드하고 인코딩 후 결과물을 받아보는 것이 모두 연결된 스토리지 계정을 통해 이루어지고, 미디어 서비스 자체는 현재 프리뷰 프로그램 상태에 있기 때문에 미디어 서비스를 통해서 실행되는 비용은 발생하지 않지만 스토리지에 파일을 보관하고 트랜잭션이 발생하는 것에 대해서는 비용이 따로 계산이 됩니다.

.NET Framework 기반 미디어 서비스 API 개발 환경 구성하기

.NET Framework로 미디어 서비스 API를 호출하기 위해서는 제공되는 SDK를 사용하는 방법이 가장 유용하고 편리합니다. 이를 위해서는 몇 가지 소프트웨어 패키지를 설치해야 하며, 다음의 패키지를 다운로드하여 설치하시면 됩니다.

미디어 서비스 API 자체가 REST API이므로 .NET 이외의 언어에서도 얼마든지 호출이 가능합니다. 기타 언어에 대한 SDK 및 지원 내용, 구성 방법은 아래의 각 링크를 참고하시면 됩니다.

테스트 프로젝트 구성하기

이 예제에서는 Windows 데스크톱 응용프로그램 환경에서 코드를 작성하는 것을 기준으로 예를 들어보겠습니다. Visual Web Developer 2010 SP1이나 Visual Studio 2012 for Web RC를 설치한 경우, Windows 클래스 라이브러리 프로젝트를 만들고 프로젝트 속성에서 프로젝트의 출력 유형을 클래스 라이브러리에서 콘솔이나 Windows로 변경하면 직접 실행 가능한 EXE 파일로 빌드 결과물을 만들 수 있습니다.

콘솔 프로그램을 하나 만들고, 프로젝트 참조에 필요한 라이브러리들을 모두 추가해야합니다.

우선 WCF Data Service 5.0 for OData v3 어셈블리들을 추가해야 합니다. 64비트 컴퓨터를 사용 중인 경우 %programfiles(x86)%\Microsoft WCF Data Services\5.0\bin\.NETFramework 폴더를, 32비트 컴퓨터를 사용 중인 경우 %programfiles%\Microsoft WCF Data Services\5.0\bin\.NETFramework 폴더에 있는 아래의 5개 DLL을 참조로 추가합니다.

  • Microsoft.Data.Edm.dll
  • Microsoft.Data.OData.dll
  • Microsoft.Data.Services.Client.dll
  • Microsoft.Data.Services.dll
  • System.Spatial.dll

이어서 Windows Azure Storage Client 어셈블리를 추가해야 합니다. %programfiles%\Microsoft SDKs\Windows Azure\.NET SDK\2012-06\bin 폴더로 이동하여 아래의 DLL을 참조로 추가합니다.

  • Microsoft.WindowsAzure.StorageClient.dll

이어서 Windows Azure Media Service SDK 어셈블리를 추가해야 합니다. 64비트 컴퓨터를 사용 중인 경우 %programfiles(x86)%\Microsoft SDKs\Windows Azure Media Services\Services\v1.0 폴더를, 32비트 컴퓨터를 사용 중인 경우 %programfiles%\Microsoft SDKs\Windows Azure Media Services\Services\v1.0 폴더에 있는 아래의 DLL을 참조로 추가합니다.

  • Microsoft.WindowsAzure.MediaServices.Client.dll

마지막으로, Windows Azure Media Service SDK가 필요로 하는 Azure Storage Client DLL의 어셈블리 버전에 대하여 바인딩 리디렉션을 지정하여 Azure Media Service SDK가 최신 버전의 Windows Azure Storage Client 라이브러리와 상호작용할 수 있도록 조정해야 합니다. 이를 위하여 프로젝트에 app.config 파일 (웹의 경우 web.config 파일)을 추가하여 아래의 섹션을 추가합니다.

<?xml version="1.0"?>
<configuration>
...
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.WindowsAzure.StorageClient"
          publicKeyToken="31bf3856ad364e35"
          culture="neutral" />
        <bindingRedirect oldVersion="1.1.0.0" newVersion="1.7.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
...
</configuration>

설치한 Azure SDK의 버전이 1.6 버전인 경우 위의 예제 코드에서 1.7.0.0 대신 1.6.0.0으로 지정하면 됩니다. 저의 경우, Windows 8용 Azure SDK를 설치했기 때문에 1.7 버전으로 지정하였습니다.

테스트 프로젝트 코딩하기

아래의 프로그램 코드를 잠시 살펴보겠습니다.

using System;
using System.Linq;
using Microsoft.WindowsAzure.MediaServices.Client;

namespace MediaServiceTestDrive
{
    class Program
    {
        static void Main(string[] args)
        {
            CloudMediaContext mediaContext = new CloudMediaContext(
                "" /* Account Name */,
                "" /* Account Key */
                );

            IAsset asset = mediaContext.Assets.Create(
                "" /* File Path */,
                AssetCreationOptions.CommonEncryptionProtected);

            IJob job = mediaContext.Jobs.Create("Sample Job");

            IMediaProcessor mediaProcessor = mediaContext
                .MediaProcessors.Where(x => x.Name == "Windows Azure Media Encoder")
                .FirstOrDefault();

            ITask task = job.Tasks.AddNew(
                "Sample task", mediaProcessor,
                "H.264 256k DSL CBR" /* Encoding Template Name */,
                TaskCreationOptions.None);

            task.InputMediaAssets.Add(asset);
            task.OutputMediaAssets.AddNew(
                "Output asset",
                true, AssetCreationOptions.None);

            job.Submit();

            while (true)
            {
                foreach (var eachJob in mediaContext.Jobs.ToList())
                {
                    Console.WriteLine(eachJob.State);
                }
                System.Threading.Thread.Sleep(5000);
            }
        }
    }
}

호출 절차가 다소 복잡해 보이지만 논리적으로 여러 작업들을 비동기 방식으로 찾아볼 수 있도록 구성한 것이 특징입니다. 우선 제일 먼저 CloudMediaServiceContext 클래스의 인스턴스를 만들어 연결을 성립시킵니다. 이 과정에서 계정 이름과 비밀 키 값을 요구하는 데 이 부분은 manage.windowsazure.com에 나와있는 미디어 서비스의 계정 이름과 키 값을 지정하면 됩니다. 스토리지 서비스에 대한 계정 이름과 키 값이 아님을 유의합니다. 스토리지 서비스에 대한 계정 이름과 키 값은 미디어 서비스 내부에서 별도로 동기화하여 보관하는 기능이 있으므로 이를 참고합니다.

그 다음 파일을 스토리지에 올리기 위한 절차이자 인코딩 대상을 지정하기 위한 절차로 Asset을 만듭니다. Asset을 만들 때 지정하는 인수에는 로컬 컴퓨터의 미디어 파일의 경로를 지정하며, 이것을 스토리지에 업로드하기 위하여 시간이 다소 걸릴 수 있습니다.

그 다음으로 작업을 하나 정의합니다. 작업 안에는 여러 가지의 세부 태스크가 존재할 수 있으며 이것을 논리적으로 하나의 작업으로 취급합니다.

그 다음에는 수행하려는 작업을 처리해줄 수 있는 미디어 프로세서 개체를 가져와야 합니다. 프로세서는 Azure Media Service가 제공하는 범위 안에서만 사용이 가능함에 유의합니다. LINQ 식을 사용하여 미디어 프로세서 개체를 확인하고 그 중 필요한 것을 택합니다. 여기서는 단순 인코딩 처리를 위하여 Windows Azure Media Encoder를 선택합니다.

그 다음으로 작업에 태스크를 하나 추가합니다. 태스크를 추가할 때에는 태스크의 이름과 미디어 프로세서 개체, 미디어 프로세서의 동작 특성을 정의하는 인코딩 템플릿 이름 등을 지정합니다. Windows Azure Media Encoder의 경우 인코딩 템플릿 이름에 대한 정보를 Expression Encoder SDK에서 확인할 수 있습니다. 이름들에 대한 목록은 http://msdn.microsoft.com/en-us/library/microsoft.expression.encoder.presets_members.aspx 에서 확인 가능합니다.

만들어진 태스크의 입력과 출력 대상을 정의하는데, 앞서 지정한 asset을 입력에 추가하고, 출력에는 새로운 asset을 생성하도록 예약합니다.

모든 구성이 끝나면 Job 객체의 Submit() 메서드를 호출하여 작업을 의뢰합니다. 이 떄 부터 모니터링 기능을 사용하여 작업의 진행 상황을 실시간으로 질의할 수 있습니다. 각각의 작업이 완료되면 State 속성이 Completed로 나타나므로 이를 통해서 작업 완료 여부를 확인 가능합니다.

실제로 어떻게 결과물이 나타나는가?

스토리지를 실제로 접속해 보면 새로운 컨테이너들이 만들어집니다. 입력용 Asset을 위한 전용 컨테이너가 먼저 만들어지고, 출력용 Asset을 위한 전용 컨테이너가 나중에 만들어지는 순서입니다. 각각의 컨테이너들은 초기에는 비공개 상태로 설정되어있습니다.

입력용 컨테이너로 만들어진 것을 열어보면 요청한 파일어 업로드된 것을 볼 수 있습니다.

출력용 컨테이너에는 기대한대로 인코딩된 파일과 메타 데이터 파일이 들어있습니다. 

출력용 컨테이너 폴더의 퍼미션 설정을 BLOB 공개로 전환하고 CDN을 연결하면 즉시 서비스 가능한 동영상이 제공되는 것입니다.

좀 더 자세한 정보를 보려면?

간단하게 한 페이지 안에 기본적인 코딩 레시피를 모아놓은 페이지가 있으므로 이 이후에 좀 더 구체적인 작업을 하기 원한다면 아래 페이지에서 내용을 확인하기 바랍니다. PlayReady와 같은 DRM 적용도 매우 쉽게 수행할 수 있습니다.

http://go.microsoft.com/fwlink/?LinkId=251359&clcid=0x412

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2012. 5. 31. 13:53

안녕하세요. Windows Azure MVP 남정현입니다.

Windows Azure Platform에 대해 많은 정보를 찾아보실 수 있도록 그 동안은 Windows Azure 카페 대문을 통하여 Feed Burner를 통해 RSS 방송국 서비스를 제공해드렸었는데요, 이번에 새로 런칭한 리클스 매거진 서비스를 통하여 RSS 방송국의 피드를 따로 엄선하여 잘 정리된 형태의 매거진으로 받아보실 수 있도록 커뮤니티 서비스를 새로 시작하고자 합니다.

현재는 창간 예비호를 발행하였고 여섯 편의 아티클을 선정하였고 다음 창간호 때에는 내용을 좀 더 엄선하여 유용한 정보를 드릴 수 있도록 하겠습니다.

http://www.licls.com/rkttu

위의 웹 사이트에도 자주 방문해주시기 바랍니다.

감사합니다.

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Azure Storage/Database2012. 5. 25. 01:02

안녕하세요. Windows Azure MVP 남정현입니다.

SQL Azure를 사용한다면 아마 거의 예외없이 접속하는 클라이언트 측의 운영 체제는 Windows 운영 체제일 것입니다. 그러나 만약 리눅스를 클라이언트 측의 운영 체제로 직접 사용하기 원한다면 어떻게 해야 할까요? 기존에 여러분이 사용하고 있을 가능성이 높은 드라이버로 FreeTDS가 있겠습니다만 버전이 낮은 드라이버는 SQL Azure가 철칙으로 사용하는 SSL 연결을 지원하지 못합니다. 최근에 출시된 FreeTDS의 경우 SSL을 지원하기는 하지만, SQL Azure로 연결을 시도할 경우 연결 과정에서 응답 없음 상태로 빠지거나 여러가지 다른 오류가 발생할 수 있습니다. 아마도 향후에 개선될 것으로 기대합니다. 이 블로그에서 설명하려는 내용에 대해 최상의 결과를 얻기 위하여 현재는 Microsoft SQL Server ODBC Driver 1.0 for Linux가 필요합니다.

시스템 요구 사항

Microsoft SQL Server ODBC Driver for Linux를 설치하기 위해서는 다음의 조건을 만족해야 합니다.

  • 64비트 지원 프로세서가 필요합니다. (x64 또는 AMD64)
  • CentOS, Fedora, RHEL 등의 Redhat 계통의 최신 리눅스 운영 체제가 필요합니다.
  • 실행 중인 운영 체제의 커널이 x86_64 환경에서 실행 중이어야 합니다.

그리고 당연한 이야기이지만 시스템 관리자 권한을 얻은 상태에서 실행해야 합니다.

설치 전에 필요한 모든 패키지 설치하기

운영 체제의 버전마다 필요로 하는 패키지의 최소 버전에 차이가 존재하기는 하나, 아래의 명령어들을 사용하여 일반적인 종속성 상의 요구 사항을 모두 정리할 수 있습니다. 아래 명령어들은 설치 전후반에 걸쳐 필요한 패키지들을 모두 설치해 줄 것입니다.

  • yum install glibc
  • yum install e2fsprogs
  • yum install krb5-libs
  • yum install openssl
  • yum install libgcc
  • yum install libstdc++
  • yum install make
  • yum install gcc
  • yum install bison
  • yum install byacc
  • yum install libuuid
  • yum install wget
  • yum install tar

드라이버 파일 내려 받기

드라이버 파일을 내려받기 위하여 http://www.microsoft.com/en-us/download/details.aspx?id=28160 페이지에서 적절한 버전의 tar 패키지 파일을 내려 받아야 합니다. 만약 서버 환경에서 직접 설치해야 하는 상황인 경우, 다운로드 URL을 확인하여 bit.ly 등의 단축 주소로 주소를 줄이고 그 주소를 wget 명령에 대입하면 수고스러움을 덜 수 있습니다.

파일을 다운로드하고나서 tar 유틸리티로 압축을 해제합니다.

tar xvzf sqlncli-11.0.1790.0.tar.gz

그 이후에는 해당 디렉터리로 이동한 다음 필요한 작업을 진행합니다.

unixODBC Driver Manager 설치하기

SQL Server Driver for Linux는 unixODBC 환경 아래에서 작동하도록 만들어진 드라이버이므로 반드시 unixODBC Driver Manager를 시스템에 설치해야 합니다. 만약 기존에 이미 설치가 되어있는 상태이면 다음 섹션으로 넘어가서 곧바로 드라이버를 설치해도 됩니다.

아래 명령어를 sqlncli 디렉터리에서 실행합니다.

./build_dm.sh

상세한 안내 메시지가 나타나게 되는데, YES를 입력하여 내용에 동의함을 표시합니다. 그 다음에는 unixODBC를 대신 다운로드하고 컴파일하고 설치하는 작업이 자동으로 진행될 것입니다. 그리고 최종적으로 사용자가 직접 설치를 진행해야 하는데, 스크립트 실행이 완료되면 아래와 같은 메시지를 볼 수 있을 것입니다. 메시지에 실제로 출력된 임시 경로로 이동하도록 정확히 이름을 지정하는 것에 유의하여 아래와 유사한 명령어를 실행합니다.

cd /tmp/unixODBC.x.x.x/unixODBC-2.3.0; make install

Linux나 Unix 명령어에 익숙하지 않은 분들을 위하여 부연 설명을 드리면, 세미콜론은 순차적인 실행을 위하여 사용되는 연산자입니다. 즉, 디렉터리를 이동하고난 다음에 make install 명령어를 실행하라는 의미입니다. 설치가 끝나고 나면 다시 sqlncli 디렉터리로 이동합니다.

ODBCINST.INI 파일 백업하기

실제 드라이버를 설치하기 전에 만약 odbcinst.ini 파일을 백업해야 할 필요가 있다면 아래 명령어를 사용하여 정확한 경로를 확인하고 해당 파일을 복사하여 백업하기 바랍니다.

odbc_config odbcinstini

실제 드라이버 설치하기

이제 실제 드라이버를 설치할 차례입니다. sqlncli 디렉터리로 이동한 다음, 아래와 같이 명령어를 입력합니다.

./install.sh install

사용자 계약서를 표시하는데, 모두 읽어보기 귀찮으시다면 키보드의 q키를 누릅니다. 그러면 동의 여부를 곧바로 묻는 프롬프트가 나오는데 여기서 YES를 입력하고 기다립니다. 특별한 오류 없이 설치가 끝났다면 마지막으로 아래 명령어를 입력하여 정상적으로 설치가 되었는지 확인해봅니다.

./install.sh verify

특별한 오류 메시지가 없다면 정상적으로 설치가 완료된 것입니다.

SQL Azure 연결 테스트해보기

이제 리눅스 환경에서도 SQL Azure에 연결이 잘 되는지 확인해볼 차례입니다. ODBC를 사용한다고 하였지만 별도로 인스턴스를 등록하거나 복잡한 절차를 거치지 않고 곧바로 테스트해볼 방법이 있는데, FreeTDS와 마찬가지로, 그리고 FreeTDS가 그러했듯이 Microsoft가 제공하는 sqlcmd 유틸리티가 여기에서도 그대로 제공됩니다.

sqlcmd -U <SQL Azure 계정 ID> -P <SQL Azure 비밀 번호> -S <서버 ID>.database.windows.net -d <데이터베이스 이름>

Windows에서 사용하던 것과 다르지 않음을 알 수 있습니다. 정상적으로 접속이 되면 1> 프롬프트가 나타날 것이고, 여기에 아래와 같이 쿼리를 수행해 봅니다.

select @@version
go

그러면 아래 그림과 같이 결과가 나타나는 것을 볼 수 있습니다. 보시는 것과 같이 SQL Azure를 Linux에서도 Native Driver를 사용하여 접속할 수 있습니다. :-)

결론

다소 복잡한 내용들이었지만, 리눅스에서도 SQL Server와 SQL Azure를 얼마든지 접근하고 다룰 수 있는 방법이 있기 때문에 데이터베이스 때문에 Windows를 써야 하는 불편함을 감수해야 할 필요가 전혀 없다는 것을 확인하였습니다. 향후에는 더 나은 방법으로 더 리눅스 환경에서 최적화된 형태로 SQL Azure나 SQL Server에 접속할 수 있을 것으로 기대합니다. 아티클에 대해서 개선할 점이나 의견을 주실 부분이 있으시면 언제든 의견을 주십시오.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2012. 5. 14. 01:07

Windows Azure VM Role을 이용하여 Base Image를 최초로 만들 때 가장 많이 시행 착오를 겪는 부분 중에 하나는 초기 Base Image의 VHD 파일 크기를 정확히 확인하지 않고 만들게 되는 부분인데, 이렇게 만들고나면 VHD 파일을 축소하는 방향으로는 수정할 수 없어서 작업이 번거로워집니다. 이러한 시행착오를 사전에 예방할 수 있도록 도움을 드리기 위하여, 개인적으로 이러한 Base Image VHD 파일들을 템플릿으로 만들어서 공유합니다.

업로드한 이미지 파일들은 Master Boot Record (MBR) 영역을 차지하도록 만들어진 단일 NTFS Primary Partition을 가지도록 포맷되었으며, 곧바로 설치에 쓰일 수 있도록 구성되어있습니다.

위의 파일들은 모두 RAR 형식으로 최고 압축률을 사용하여 압축하도록 만들어진 파일들로, 압축 해제를 위해서는 WinRAR 또는 최신 버전의 RAR 유틸리티가 필요하며, 압축을 해제하려면 파일을 저장할 파티션의 잔여 공간이 VHD 파일을 포함하여 충분한 공간이 남아있어야 합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2012. 4. 17. 11:55

ASP.NET 환경에서 사용자 멤버십, 프로파일, 역할과 세션 상태 관련 기능은 별도의 공급자 클래스에 의하여 구현되는 경우가 많은데, 이러한 공급자 클래스들은 개발자 스스로 원한다면 별도로 정의하여 각자의 서버 및 네트워크 인프라에 맞추어 다시 작성할 수 있습니다. 하지만 이렇게 작업하기에는 녹록치 않은 면들이 많고, 또 실제로 많은 테스트와 검증 과정이 뒷받침되어야 할 필요가 있습니다.

최근에는 SQL Server Compact Edition이나 SQL Server 2012에서 소개된 SqlExpress 또는 SQL Azure와 같이 전통적인 SQL Server 환경이 아닌 곳을 기반으로 택해야 하는 일도 자주 있습니다. 이러한 경우 많은 시행 착오와 오류를 경험할 수 밖에 없는데, 이러한 문제를 크게 덜어줄 유용한 기술이 하나 있습니다. 바로 ASP.NET Universal Provider이며, 향후 Microsoft가 언급하는 Hybrid Cloud Computing 환경에서의 단일 프로그래밍 모델을 구현하기 위한 초석으로 자리매김할 것으로 예상됩니다. :-)

ASP.NET Universal Provider의 구성

ASP.NET Universal Provider는 다음과 같은 구성을 가지고 있습니다.

  • System.Web.Providers.DefaultMembershipProvider
    (기존의 System.Web.Security.SqlMembershipProvider에 대응)
  • System.Web.Providers.DefaultProfileProvider
    (기존의 System.Web.Profile.SqlProfileProvider에 대응)
  • System.Web.Providers.DefaultRoleProvider
    (기존의 System.Web.Security.SqlRoleProvider에 대응)
  • System.Web.Providers.DefaultSessionStateProvider
    (내장된 세션 상태 관리 공급자를 대체)

ASP.NET Universal Provider를 Visual Studio의 확장 패키지 갤러리 (NuGet 갤러리)를 통하여 설치하게되면 위의 각 공급자에 대한 설정을 현재 ASP.NET 프로젝트 상의 web.config 파일에 지정하게되고, 데이터 소스를 어떻게 선택하는지에 따라서 미리 구성된 데이터 스키마에 맞추어 관련된 서비스 기능을 수행할 수 있도록 맞추게 됩니다.

ASP.NET Universal Provider 설치하기

ASP.NET Universal Provider는 Nuget Package Install Site에서 손쉽게 asp.net 프로젝트에 추가할 수 있습니다. Visual Studio나 Visual Web Developer를 설치한 경우 Nuget Console에서 아래 패키지 이름을 검색하여 기존 프로젝트에 추가하시면 됩니다. 

패키지 설치가 끝나면 web.config 파일에 아래와 같이 Membership, Role, Profile, Session State에 대한 설정을 Universal Provider로 업데이트합니다.

<configuration>
    <connectionStrings>
        <add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\aspnet.mdf;Initial Catalog=aspnet;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient"/>
    </connectionStrings>
    <system.web>
      <profile defaultProvider="DefaultProfileProvider" >
        <providers>
          <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider" connectionStringName="DefaultConnection" applicationName="/"/>
        </providers>
      </profile>
      <membership defaultProvider="DefaultMembershipProvider">
        <providers>
           <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider" connectionStringName="DefaultConnection"
             enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
             applicationName="/" />
        </providers>
      </membership>
      <roleManager defaultProvider="DefaultRoleProvider">
        <providers>
           <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider" connectionStringName="DefaultConnection" applicationName="/" />
        </providers>
      </roleManager>
      <sessionState mode="Custom" customProvider="DefaultSessionProvider">
        <providers>
          <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider" connectionStringName="DefaultConnection" applicationName="/"/>
        </providers>
      </sessionState>
    </system.web>

위의 설정에서 DefaultConnection에 적절한 연결 문자열과 함께 정확한 providerName을 기재하면 Universal Provider가 정확한 ADO.NET Connection Driver를 사용하여 필요한 서비스들을 제공하게 됩니다. 이렇게 만듦으로서 SQL Azure는 물론 기존 SQL Server, SQL Server CE를 데이터 원본으로 선택할 수도 있습니다.

좀 더 자세한 정보 알아보기

패키지의 최신 업데이트 정보와 설치 방법은 아래 웹 사이트에서 확인할 것을 권합니다.

http://nuget.org/packages/System.Web.Providers/1.0.1

구체적인 사용 방법과 시나리오에 대해서는 Scott Hanselman의 블로그 아티클을 참고하시기 바랍니다.

http://www.hanselman.com/blog/IntroducingSystemWebProvidersASPNETUniversalProvidersForSessionMembershipRolesAndUserProfileOnSQLCompactAndSQLAzure.aspx

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2012. 3. 28. 01:39

안녕하세요. Windows Azure MVP 남정현입니다.

올해 첫 세미나는 Microsoft MVP 지식 나눔 강연에서 인사드리는 것으로 시작하게 되었습니다. 이번 지식 나눔 강연 세미나는 Imagine Cup 2012 소프트웨어 디자인 한국 대표 선발전과 맞물려서 인천대학교 캠퍼스 내에서 진행되는 특별한 행사이며, 박찬 MVP님, 권순만 MVP님, 박성기 MVP님, 고재관 MVP님, 고경희 MVP님과 저를 포함하여 2012년 3월 29일 목요일 하루 동안 공동 세미나를 엽니다. 자세한 행사 목차는 아래 포스터 이미지를 참고하여 주십시오.

제가 진행하는 세션에서는 Windows Azure를 활용한 Cloud 개발 사례를 소개합니다. 발표 자료는 아래 내용과 같습니다.

감사합니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

기술 소식2012. 1. 5. 09:59

Windows Azure에서 리눅스를 게스트 OS로 2012년 중에 지원을 추가할 예정입니다.

Microsoft 전문 테크니컬 칼럼니스트인 Mary-Jo Foley의 기사에 따르면, Microsoft가 2012년 중에 리눅스를 실행할 수 있도록 Windows Azure 서비스를 업데이트할 예정이라고 합니다. 워낙에 특이하고 걸출한 토픽인지라 이 기사 자체가 잘못된 것이 아니냐는 반문을 살 정도로 뜨거운 이슈인 것 같습니다. :-)

현재 나와있는 Web Role, Worker Role은 Visual Studio를 이용하여 개발자가 Application Instance를 패키징해서 Windows Azure에 배포할 때 이것을 VM으로 변환하여 Windows Server 2008이나 Windows Server 2008 R2에서 실행할 수 있도록 바꾸고 있고, 작년에 나온 VM Role은 여기서 좀 더 나아가서 VHD 안에 Windows Server 2008 R2를 설치하고 VHD 단위로 VM을 만들 수 있도록 하는 기능을 내놓았습니다. 그러나 지금까지 나온 것은 모두 한 가지 기술적 특징이 있는데, 실행 중인 VM이 예고 없이 자동으로 재시작되거나 초기화될 수 있다는 점입니다. 그래서 Windows Azure 기반으로 서비스를 개발할 때에는 VM 안에 상태를 보관하는 방식 대신 Stateless/Remote Storage를 활용하는 전략을 택해야 했었습니다.

하지만 Linux VM에 대한 지원과 더불어 장기 실행 VM이 Windows Server에 대해서도 같이 제공되어 Amazon Web Service의 Elastic Cloud Computing 서비스와 같은 형태의 VM Hosting을 Windows Azure에서도 사용할 수 있을 것으로 보입니다. 현재 예상되는 리눅스 배포판으로는 CentOS, RHEL, Suse Linux 등 기존의 Hyper-V 스택에서 원활하게 구동 가능한 상용 리눅스 배포판 대부분이 여기에 포함될 것으로 보입니다.

지금 소개하는 기능은 CTP 버전으로 올해 봄 (2012년 봄) 시즌에 새로 런칭될 것으로 보입니다. 그리고 이 외에도 SharePoint 서버와 SQL Server를 탑재한 가상 머신 이미지의 배포도 같이 지원함으로서 SQL Azure 특유의 기술적 한계를 보완하고 Private Domain에서 사용 가능한 SQL Server를 Windows Azure에서도 이용할 수 있을 것으로 보입니다.

좀 더 자세한 내용은 http://www.zdnet.com/blog/microsoft/microsoft-to-enable-linux-on-its-windows-azure-cloud-in-2012/11508 에서 보실 수 있습니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2011. 12. 15. 10:11

최근 개편된 Windows Azure 웹 사이트에서 한 가지 재미있는 내용을 발견하였는데, 이전에는 Windows Azure AppFabric의 일부로 Service Bus, Access Control가 제공되는 것으로 언급되었지만 이번에는 Windows Azure라는 단일 브랜드의 서비스 구성 요소로 통합되었습니다. 이를 두고 여러 가지 이야기가 있었지만 결론은 Windows Azure Platform 아래에 모든 서비스를 하나로 통합시키겠다는 의도 아래에 이루어진 정리 작업이었습니다.

개편된 웹 사이트: http://www.windowsazure.com/en-us/home/tour/overview/

서비스 브랜드 네임의 조정이 있었지만 서비스 다운 타임이 생겼다던지 혹은 다른 문제점이 있었던 것은 전혀 아닙니다. 하지만 앞으로는 Azure AppFabric와 Server AppFabric을 혼동할 이유가 없을 것입니다. Azure AppFabric의 구성 요소들은 모두 Windows Azure Platform의 서비스들이고, Server AppFabric의 구성 요소들은 지금까지와 마찬가지로 독립적인 노선을 유지하게 될 것 같습니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

기술 소식2011. 9. 27. 13:46

Windows Azure Platform의 핵심 구성 요소들 중 하나인 Windows Azure Storage가 이번 BUILD Windows 2011 행사 이튿날에 발표한 기능 중에는 Windows Azure Storage의 향상에 관한 내용이 있었는데, 그 동안 Windows Azure Storage에 대해서 바라던 많은 요구 사항들이 이번에도 성실하게 반영되었습니다. 그 중에서도 큰 맥락을 나누면 같은 지역 내의 다른 데이터센터로 Storage의 데이터를 복제할 수 있는 Geo-Replication 기능과, BLOB, Table, Queue 스토리지의 사용법 개선에 따른 성능 향상이 있습니다.

Geo-Replication

이제 Windows Azure Storage 역시 다른 Cloud Platform들과 마찬가지로 재해 복구 기능을 가질 수 있게 되었습니다. 기존에는 Geo-Replication을 전적으로 이용자의 재량으로 해야했고, 비용 투자가 필요했던 부분이지만 이 기능을 네이티브하게 지원할 수 있게 되었기 때문에 더 안전한 서비스 사용이 가능해지게 되었습니다. Geo-Replication은 Windows Azure BLOB과 Table 스토리지에 한정되는 내용으로 예를 들어 북유럽과 서유럽 사이, 동아시아와 동남아시아 사이의 데이터센터 간에 데이터 복제를 수행하여 Redundancy를 확보하는 전략입니다. 그러나 아시아와 유럽 간 복제는 수행하지 않으며, 모든 작업은 비동기적으로 수행되므로 현재 서비스에서 변경되거나 영향을 주는 부분은 없다고 합니다. 

새 BLOB, Table 및 Queue 스토리지의 기능들

2011-08-18 버전의 REST API에서는 기존에 커뮤니티로부터 많은 요청이 있었던 기능들을 제공하는데, 다음과

  • Table Upsert: 한 번의 요청으로 이미 존재하는 엔터티에 대해서는 업데이트를, 존재하지 않는 엔터티에 대해서는 삽입을 조건부로 처리할 수 있는 기능입니다.
  • Projection Query 지원: 엔터티의 하위 집합을 만들 수 있는 기능으로 LINQ to Table Storage 등에 직접적인 영향을 주게 될 가장 큰 기능입니다. 이전에는 Projection Query를 수행할 수 없었기 때문에 전체 엔터티 컬렉션을 서버로부터 우선 다운로드한 다음 이것을 메모리에서 정리하는 비효율적인 방식을 사용했지만 이 작업을 서버 차원에서 직접 수행할 수 있게 됨에 따라 대역폭 사용량을 줄이고 쿼리 성능을 더 업그레이드할 수 있게 되었습니다.
  • 향상된 BLOB HTTP 헤더 지원: BLOB 차원의 동영상 스트리밍이 가능해지고, 다운로드 가속기 등으로 이어받는 작업이 가능해졌습니다.
  • 큐 메시지 업데이트: 큐에 삽입한 메시지의 내용을 편집하거나, 유효 기한을 연장하여 큐 자체의 항목을 엔터티로 취급할 수 있게 하고 길게 소요되는 작업에 대한 이벤트 처리를 큐 스토리지를 통해서 할 수 있도록 기능을 보강했습니다.
  • 큐 메시지 삽입 시 대기 시간 지정: 큐에 메시지를 삽입한 직후에 다른 큐 메시지 수신처에서 내용을 보이게 하지 않고, 지정된 기간 동안 내용을 숨기도록 삽입할 수 있습니d

그 외에 좀 더 자세한 정보는 아래 블로그 문서들을 참고하십시오.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2011. 9. 12. 23:32

요즈음 클라우드 서비스들을 이용하다보면, Windows 서버 운영체제를 통해서 확장성있는 클라우드를 만들고자 하는 경우가 자주 있습니다. 일반적인 웹 사이트를 구축할 때에도 마찬가지이고, 당연히 KT UCLOUD나 Amazon과 같은 환경에서도 같은 노력이 뒷받침이 되어야 하지요. 그리고 제가 주 전공으로 하고 있는 Windows Azure 역시, 첫 배포 때에는 간과하기 쉬운 점이 바로 로드 밸런싱 환경이라는 점입니다.

이러한 로드밸런싱 환경을 만들때에는, 이전에 구축해본 경험이 없는 관리자가 개발자 입장에서는 상당히 어려운 문제에 봉착하게 될 가능성이 많습니다. 특히 요즈음 웹 환경에서는 당연하게 사용하는 세션이나 쿠키에 관련된 설정들이 로드밸런싱 환경에서 기대했던 것과 다르게 동작해서 좌절하는 경험을 많이들 하실텐데요, 제가 오늘 블로그에 올리는 것은 ASP.NET에 관한, 그리고 IIS 7에 관한 내용입니다. (PHP나 JSP 개발자분들께서도 공감하실 수 있는 부분이 있을 것입니다.)

로드밸런싱 환경을 잘 알고 구축할 수 있다면, 앞으로 나오게될 어떤 종류의 클라우드 서비스이든 관계없이 문제를 정확하게 해결할 수 있을 것입니다. 사실 클라우드 기반의 웹 서비스는 달리 표현하면, 기본 골자는 로드밸런싱에 기반을 두고 있는 것이고, 그 이후의 확장성 전략을 클라우드 솔루션으로 채우는 것과 같다고 말할 수 있습니다. (어떤 뼈대를 사용할 것인지는 전적으로 여러분들의 선택에 달린 것입니다.)

로드 밸런싱 환경이란?

로드 밸런싱 기술 자체는 상당히 오래된 것입니다. 이름에서 알 수 있듯이, 몰려오는 트래픽을 내부적으로 분산하여 특정 서버 컴퓨터로 연결이 몰려 서비스가 사용 불가 상태로 빠지는 것을 "지연"시키거나 "완화"시키는 것에 목적이 있습니다. 로드 밸런싱의 기술적 개념도는 다음과 같습니다. (이미지 출처: http://msdn.microsoft.com/en-us/library/ff650667.aspx)

다양한 상황에서 로드밸런싱이 쓰이겠지만 가장 일반적으로는 웹 환경에서 많이 쓰입니다. 연결을 오래 유지할 필요가 없으면서도, 짧은 시간 내에 빠른 연결 회전을 보이는 웹 프로토콜에서 가장 중요한 것은 바로 신속성인데, 분산 처리를 하지 않는 경우에는 필연적으로 서버 컴퓨터가 받아들일 수 있는 동시 연결 한계치에 금방 치닫게 됩니다. 그러나 로드 밸런싱을 정확히 사용하면 이러한 한계치에 치닫게 되는 속도가 로드 밸런싱에 참가하는 컴퓨터의 댓수만큼 반비례하게 됩니다. 그리고 이 때 하나의 웹 사이트를 위한 로드 밸런싱 서비스에 멤버로 참여하는 서버 컴퓨터들을 묶어서 "웹 팜"이라고 정의를 하는 것이지요. 더 일반적으로는 "서버 팜"이라고도 합니다.

잠시 다른 이야기로 넘어가자면, 요즈음 대두되는 클라우드 컴퓨팅은 관리 측면에서 봤을 때, 충분한 대역폭을 보장하는 연결과 매우 뛰어난 성능을 가진 로드 밸런서를 이용하여 연결을 분산하는 작업을 수행하는 것입니다. 그리고 웹 팜 안에 참여하는 컴퓨터의 유형에 있어서는 이전과 다른 점이 하나 있는데, 마치 구름과 같이 수축과 팽창을 자유자재로 한다는 것입니다. 물론 이런 수축과 팽창이 가능함은 내부적으로 가상화 솔루션을 이용했다거나 여기에 대응할 수 있는 알고리즘을 사용했다는 가정이 깔려있는 것입니다.

정말 완벽하고 정확하게 구축했다면, 적은 전원이나 자원 공급으로도 충분히 웹 팜이 유지가 될 수도 있고, 필요하다면 웹 팜의 크기가 엄청나게 커질 수도 있겠지요. 이걸 여러분이 관리하신다면 프라이빗 클라우드, 신뢰할 수 있는 IT 기업이 관리한다면 퍼블릭 클라우드가 된다고 보실 수 있겠습니다. 그러나, 클라우드 컴퓨팅이 만능약처럼 들릴 수 있는 부분이 있지만 정확히 알아야 할 것은 클라우드 컴퓨팅 역시 이 로드 밸런싱을 기초로 만들어지는 것이고, 여러분이 운영할 수 있는 한계에까지 트래픽이 몰리거나, 이런 일을 하는 IT 업체에게 지불할 수 있는 재정의 한계에까지 트래픽이 몰린다면 이것이 여러분이 생각할 수 있는 클라우드의 한계입니다. 무제한이라고 해서 값이 저렴하거나 무료에 수렴하는게 아님을 명확히 이해하고 있어야 합니다.

웹 로드 밸런싱을 위한 이야기

다시 본론으로 돌아와서, 웹을 로드 밸런싱할 수 있으려면 무엇을 검토해야 할까요? 가장 중요한 것은 웹 서버에 참여하는 각각의 컴퓨터 자체에는 "절대로" 컴퓨터의 고유한 정보를 가지고 있으면 안된다는 점입니다. 매우 단순한 이야기같지만 이러한 원칙을 지키지 않도록 설계되어있는 것이 지금 이 시점까지의 서버 컴퓨팅 기술들의 대다수의 원칙입니다. 간단한 예를 들어볼까요?

여러분이 일상적으로 사용하는, 웹을 통한 파일 업로드 기능을 담당하는 간단한 웹 앱이 있다고 가정해 보겠습니다. 이 웹 앱은 서버가 한 대 일때에는 참 쉽고 빠르게 설치해서 쓸 수 있었습니다. 당연히, 설치를 잘 했다면, 사용자가 웹 페이지를 방문해서 파일을 업로드하면 웹 서버가 그것을 알아보고 파일을 회수해서 하드 디스크 어딘가에 저장하겠지요. 그러나 시간이 지나서 이 웹 앱의 기능을 업그레이드하고 좀 더 많은 사용자들이 파일을 저장하고 다운로드할 수 있도록 만들어보고자 해서 로드 밸런싱 환경을 구축하여 베타 테스트를 시작했습니다. 그런데 어떤 문제들이 생겼을까요?

앞서 이야기한 기술적인 특성때문에, 사용자들은 분명히 조금전까지 파일을 업로드했었는데 페이지를 다시 와서보니 파일이 업로드되지 않은 상태로 페이지가 나와서 혼란스러워합니다. 혹은 파일을 어디로 빼돌린거냐며 분노하는 사람들도 있구요. 그래서 몇 번 F5키를 누르다보면 "어라?"하고 놀라게 됩니다. 조금 전에 업로드했던 파일이 다시 나타나니까요. 그러고나서 그 파일을 다운로드하려고 링크를 클릭하면 이번엔 또 다시 404 오류를 만납니다. 이제 사용자들은 이 서비스에 대해서 대단한 분노와 원성을 쏟아낼 것입니다. 서비스 상태에도 일관성이 없을 뿐 아니라 불안정한것 같다. 믿을 수 없다면서요.

이것이 일선 IT 현장에서 로드 밸런싱이나 클라우드를 처음 접목했을 때 겪는 "가장 흔하고 일반적인 장애"입니다. 더 안타까운 것은, 이것을 신 기술에 의한 책임으로 회피하고 문제시하는 것입니다. 문제의 본질을 정확히 알고 있다면 이렇게 말하는 것이 왜 잘못인지도 금방 알 수 있을 것입니다.

여기서 든 예제처럼, 이 웹 앱의 문제는 단순히 업로드한 파일을 자신의 컴퓨터에 저장하려고 했다는 데에 문제가 있습니다. 로드 밸런싱 멤버로 참여하는 컴퓨터가 자신의 상태를 중요하게 여기면, 다음번에 이어받는 다른 서버 컴퓨터의 입장에서는 이전에 그 컴퓨터가 무엇을 했는지 알 길이 없습니다. 그저, 찾고자 하는 내용이 없음을 이야기하는 수 밖에 없습니다. 이런 상황이 반복되면서 서비스 전체는 들어올때와 나갈때가 전혀 다른, 일관성이 없고 이상한 서비스가 되는 것입니다.

이 문제를 해결하기 위하여 어떻게 수정해야 할까요? 답은 간단합니다. 파일 저장소를 로드 밸런싱 멤버 컴퓨터 내부가 아닌, 여러 멤버 컴퓨터들이 같이 이용할 수 있는 공용 저장소로 바꾸는 것입니다. 가장 간단한 방법은 네트워크 UNC 경로로 이용할 수 있는 스토리지가 있을 수 있습니다.

여기서 궁금한 점이 하나 더 있는데, 그렇다면 로드 밸런싱에 의하여 애써 분산한 서비스가 다시 모이는 것이 아니냐고 반문할 수도 있습니다. 그런데 사실, 생각외로 사용자들이나 웹 크롤러와 같이 인터넷 상에서 발생하는 별 뜻없이 바쁘게 만드는 다양한 유형의 트래픽을 웹 팜 수준에서 한 번은 로드 밸런싱을 해주는 것 만으로도 실제 스토리지에 대한 요구 사항은 획기적으로 감소한다는 점입니다. 거기다, 역할 분담도 정확히 할 수 있으며 스토리지 자체에 대한 요구 사항이 폭증하는 것을 방지하기 위하여 기술적으로는 좀 더 복잡해질 수 있지만 캐싱 기능을 사용할 수도 있습니다. 이렇게 함으로서, 우리가 흔히 잘 아는 클라우드 서비스의 시작을 뗄 수 있게 됩니다.

기술적인 이야기 1 - 세션 처리 방법 바꾸기

그렇다면 IIS와 ASP.NET에서는 이런 이상한 상황을 예방하고 신뢰할 수 있는 서비스를 만들기 위해서 어떤 수정 사항을 반영해야 하는 것일까요? 제가 이제까지 인터넷 상으로 자료 조사를 해왔던 것은 모두 제각기 흩어져있는 정보들이었고 이것을 한 번에 취합할 수 있는 방법을 오늘 블로그 포스팅을 통하여 소개할까 합니다.

기본적으로 ASP.NET은 세션 처리를 IIS 프로세스 안에서 수행하도록 되어있습니다. 가장 동선도 짧고, 신속하게 반응하기 때문입니다. 그러나 로드 밸런싱 환경에서 이는 당연히 "채택하면 안되는" 기법입니다. 이 방법은 web.config 파일 안의 <sessionState> 요소에서 변경할 수 있는 부분으로, <configuration> 요소 아래의 <system.web> 요소 아래에서 없는 경우 새로 지정할 수 있습니다. <sessionState> 요소의 mode 속성의 값을 변경하면 됩니다. 지금 이야기한 부분은 mode 속성이 InProc으로 지정되어있거나, 아무것도 지정되어있지 않을 때 .NET Framework의 글로벌 web.config 설정을 바꾸지 않은 경우 기본으로 지정되는 설정입니다.

IIS 7에서 볼 수 있는 아래 그림과 같은 설정도 이 XML 파일의 수정을 텍스트 에디터 없이 수정하는 것입니다.

로드 밸런싱 환경에서 정상적으로 동작하는 웹 사이트를 만들기 위해서는 mode의 설정 값을 InProc 대신 StateServer나 SQLServer로 바꾸어야 하는데, 양쪽 값 모두 장단점이 있습니다. StateServer의 경우 기본적으로는 꺼져있는 ASP.NET State Service라는 NT 서비스가 제공하는 별도의 서버를 이용하는 방식이고, SQLServer는 이름에서 알 수 있듯이 실제 SQL Server를 사용하여 세션을 구현하는 방식입니다. 데이터베이스 서버의 성능이 세션을 모두 수용할 수 있을만큼 획기적으로 뛰어나거나, 세션 서버가 죽었다가 살아나도 로그아웃 처리가 안되게 한다던가, 혹은 여러 로드 밸런싱 사이트 사이에서 세션 공유를 안전하게 할 방법이 필요하다면 이 모드를 사용할 수 있습니다. 이에 비하여 StateServer는 별도의 SQL 서버 없이도 간편하게 구축할 수 있는 방법을 제공하긴 하지만, 세션 서버가 죽었다 살아날 경우 내용이 없어지는 휘발성 세션입니다.

양쪽 모드 모두 중요한 것은 멤버로 참여하는 웹 서버 컴퓨터 밖에 상태를 보관해야 한다는 것이 키 포인트로, 이것을 지키지 않고 멤버 컴퓨터 안에 이런 설정을 구축하면 전혀 나아지는 것이 없습니다. 그리고 당연한 이야기이지만 멤버 컴퓨터로 참여하는 모든 웹 서버가 같은 설정을 가지고 있어야 합니다.

StateServer와 SQLServer 모드를 구현하는 방법에 대한 자세한 내용은 아래 아티클을 참고하시면 되겠습니다.

http://msdn.microsoft.com/ko-kr/library/ms178586.aspx

기술적인 이야기 2 - ASP.NET 사이트 간에 립싱크 맞추기

세션을 공유하는 것 이외에, ASP.NET은 내부적으로 Machine Key라는 것을 사용합니다. Machine Key의 용도는 ASP.NET 안에서 참 다양한데, 가장 대표적으로는 클라이언트와 서버 사이에 쿠키 정보를 주고 받을 때 암호화하기 위한 수단으로 이용하는 것이 유명한 사례입니다. 쿠키를 이용한 취약점 공격은 웹 세계에서 너무나 당연한 공격 방식 중 하나이기 때문에 ASP.NET은 처음부터 이를 보완하기 위한 전략을 구현하고 있었습니다. 그러나 이것이 지금 와서 로드 밸런싱 환경이 되면서는 또 다른 어려운 문제로 바뀐 것입니다.

이 Machine Key라는 것 역시 서버 컴퓨터마다 고유하게 생성할 뿐 아니라, 매번 연결할 때 마다 다른 값을 생성하여 암호화에 사용합니다. 클라이언트 입장에서야, 서버가 "ABC"라는 쿠키를 주니까 "아 그렇구나. 나중에 돌려주면 서버가 날 알아보겠지?"하며 성실하게 반납합니다. 그런데 로드 밸런싱에 참여하는 A라는 서버 대신 C라는 서버가 이 쿠키를 받아들었을 때는 "이거 내것 아님" 하며 클라이언트에게 퇴짜를 놓습니다. 이것이 문제의 핵심인 것이죠.

이 문제를 해결하기 위해서는 아까전에 이야기한 주제보다 좀 더 많은 노력이 필요합니다. 생각보다, 보안을 완벽하게 유지하기 위하여 ASP.NET이 관리자들에게 요구하는 사항이 까다롭기 때문입니다. 이 Machine Key를 만들기 위해서는 별도의 생성 도구를 사용해야 합니다. 그러나 안타깝게도 이 도구를 구한다거나 만들 수 있으려면 개발자들의 조력이 좀 필요합니다. 그리고 개발자 본인들도 이런 방법을 찾아야 하기때문에 꽤나 귀찮습니다. Codeproject에 가면 이러한 방법을 자세히 설명한 아티클도 있습니다만 간단한 도구도 드리고, 코드 조각도 드리니 프로그램에 넣어 활용하시면 더 편리할 것입니다.

using System;
using System.Text;
using System.Security.Cryptography;

/* 중략 */

        public static string getRandomKey(int bytelength)
        {
            byte[] buff = new byte[bytelength];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(buff);
            StringBuilder sb = new StringBuilder(bytelength * 2);
            for (int i = 0; i < buff.Length; i++)
                sb.Append(string.Format("{0:X2}", buff[i]));
            return sb.ToString();
        }

        public static string getASPNET20machinekey()
        {
            StringBuilder aspnet20machinekey = new StringBuilder();
            string key64byte = getRandomKey(64);
            string key32byte = getRandomKey(32);
            aspnet20machinekey.Append("<machineKey\n");
            aspnet20machinekey.Append(" validationKey=\"" + key64byte + "\"\n");
            aspnet20machinekey.Append(" decryptionKey=\"" + key32byte + "\"\n");
            aspnet20machinekey.Append(" validation=\"SHA1\" decryption=\"AES\"\n");
            aspnet20machinekey.Append("/>\n");
            return aspnet20machinekey.ToString();
        }

        public static string getASPNET11machinekey()
        {
            StringBuilder aspnet11machinekey = new StringBuilder();
            string key64byte = getRandomKey(64);
            string key24byte = getRandomKey(24);

            aspnet11machinekey.Append("<machineKey");
            aspnet11machinekey.Append(" validationKey=\"" + key64byte + "\"\n");
            aspnet11machinekey.Append(" decryptionKey=\"" + key24byte + "\"\n");
            aspnet11machinekey.Append(" validation=\"SHA1\"\n");
            aspnet11machinekey.Append("/>\n");
            return aspnet11machinekey.ToString();
        }

위의 코드를 사용하여 프로그램을 만들거나 ZIP 파일 안의 프로그램을 이용하여 값을 만들도록 하면 아래와 같은 XML 코드 조각을 얻을 수 있을 것입니다. 이 코드 조각을 각각의 서버에 들어있는 web.config에 지정하거나, 특정한 값만 인용하여 아래의 IIS 7 설정 아이콘에서 볼 수 있는 설정 도구를 통해서 직접 설정할 수도 있습니다.

<machineKey
 validationKey="FACBB6C89C44CB8BB7165FC4639BAA7267B...EF297D815E1BDD40E883E3451628CB95D34309"
 decryptionKey="4E95057676CC8DBA9AB...AACC1121B6B962E5AFA7849B0C82"
 validation="SHA1" decryption="AES"
/>

기술적인 이야기 3 - IIS에서 놓치면 안되는 것

ASP.NET을 가장 먼저 사용할 수 있게 된 웹 서버가 IIS이다보니 발생한 일종의 특성입니다만 여러 포럼에 걸쳐서 잘 언급되지 않는 문제점이 하나 있습니다. 바로 IIS에서 사용하는 사이트 ID 값을 통해서 정해지는 Application Path를 Machine Key와 같이 활용된다는 사실입니다. 웹 사이트 관리를 하다보면 로드 밸런싱에 참여하는 컴퓨터들을 다음과 같이 관리하게 되는 경우가 있습니다.

  • 서버 A에서는 기본 웹 사이트를 먼저 지우고 새 웹 사이트를 만들었다.
  • 서버 B에서는 새 웹 사이트를 먼저 만들고 기본 웹 사이트를 지웠다.

혹은 아래와 같은 경우도 있을 수 있습니다.

  • 서버 C에서는 사이트 A를 만들고 사이트 B를 만들었다.
  • 서버 D에서는 사이트 B를 만들고 사이트 A를 만들었다.

별 차이 없이 생각할 수 있지만, IIS에서는 이 경우 각각의 사이트들에 다른 ID 값을 부과하게 됩니다. 이 경우, 분명히 Machine Key를 동일하게 지정했음에도 불구하고 로드 밸런싱 환경에서 세션 상태가 일관성없게 변하는 문제를 만나게 됩니다. 제가 이번에 고민하게 된 부분도 바로 이 부분이었는데요, 이 문제를 해결하기 위해서는 IIS 7에서 전체 웹 사이트 목록에 나타나는 내용 중 다음의 ID 값이 멤버로 참여하는 웹 서버마다 차이가 있지 않은지 우선 검토해야 합니다.

위에있는 그림에서 빨간색으로 그린 부분이 서버 컴퓨터마다 차이가 있다면 이 값을 수정해주어야 합니다. 이 값을 수정하기 위해서는 수정할 사이트를 클릭하고, 고급 설정 링크를 아래 그림과 같이 클릭합니다.

이제 아래와 같은 팝업 대화 상자가 나타나면 강조 표시한 속성인 ID 값이 멤버로 참여하는 웹 서버 모두 같은 값을 가질 수 있도록 통일시켜줍니다.

확인 버튼을 누른 다음, ID 값이 바뀐 서버 컴퓨터에 한해서 IIS 전체를 재시작해주시거나 사이트 재시작을 시켜주시면 정상적으로 작동하게 될 것입니다.

Windows Azure 환경에서의 고려 사항

오늘 살펴본 내용은 IIS 7과 ASP.NET에 관한 부분이었지만, Windows Azure Platform의 경우에도 비슷한 문제가 있습니다. Windows Azure Platform에 VM Role로 웹 사이트를 게시를 하든, Web Role로 웹 사이트를 게시하든 세션을 사용하게 될 경우 비슷한 문제가 있을 수 있습니다.

다행히, Web Role을 이용한다면 내부적으로 사용하는 IIS에서 여러분이 몇 개의 웹 사이트를 추가적으로 구성하든 관계없이 같은 순서로 같은 ID를 사용하는 웹 사이트를 만들 것이므로 세 번째로 이야기한 ID 값 수정과 같은 작업은 할 필요가 없을 것입니다. 그러나 Machine Key에 대한 설정이나 세션 공유를 위한 설정은 SQL Azure를 이용한다거나, Worker Role에서 ASP.NET State Service 혹은 써드파티의 Session State Server를 이용해야 할 수 있습니다.

물론, 최근에 Windows Azure Platform의 일부로 Windows Azure AppFabric Cache가 새로 출시되기는 하였습니다만 상당히 이용 가격이 비싼 편입니다. (비싼만큼 확실한 성능을 제공합니다.) 로드 밸런싱 환경에서 특별한 문제를 일으키지 않는 일반적인 세션 공유가 필요하시다면 오늘 이야기한 주제를 응용한 Azure Project를 구축해보는 것도 의미가 있을 것입니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2011. 9. 2. 09:41

세미나 신청은 http://onoffmix.com/event/3671 에서 부탁드립니다.

Windows Azure Cafe (http://cafe.naver.com/wazure)에서는 지난해에 이어 올해부터는 매월 다양한 주제를 통하여 개발자, IT 전문가들에게 Windows Azure 기반의 실전 개발에 대한 이야기를 전할 수 있또록 Boot Camp 세미나를 준비하였습니다. 클라우드 컴퓨팅에 관심이 있는 분들을 모시고, 세미나 전/후로는 클라우드 컴퓨팅과 최신 기술 동향에 대한 자유로운 토론도 같이 진행할 수 있도록 하겠습니다. 이번달에는 SQL Azure에 대한 내용을 다루어봅니다.

카페 방문하기: http://cafe.naver.com/wazure

제목: SQL Azure 실무에 도입하기
일시: 2011년 9월 7일 수요일 / 오후 7시
장소: 포스코센터 서관 5층 한국 마이크로소프트 SYNERGY 룸
대상: 소프트웨어 개발자 및 웹 개발자
발표: 남정현 (Windows Azure MVP 2011)

세션 소개

(1) SQL Azure가 SQL Server와 다른 점
SQL Azure는 Microsoft SQL Server를 클라우드 환경에서 사용할 수 있도록 서비스화하여 제공하고 있는 클라우드 서비스로, 기본 기능들은 Microsoft SQL Server와의 호환성을 유지하기 위하여 작성되었지만, 실제 동작 환경이나 여러 가지 제약 사항들이 또 한편으로는 존재합니다. SQL Azure를 이용하여 데이터베이스 프로그래밍을 어떻게 시작할 수 있고, SQL Server와의 차이점이 어떤 것들이 있는지 첫 세션에서 살펴보고자 합니다. 그리고 각 프로그래밍 언어별로 SQL Azure를 활용하는 방법도 살펴봅니다.
- 30일 Trial로 SQL Azure 계정 신청하기
- SQL Azure의 구조 살펴보고 이해하기
- Desktop 및 Server에서 SQL Azure 활용하기
- PHP나 Java에서 SQL Azure 활용하기
- Visual C++과 OLE DB를 이용하여 SQL Azure 활용하기

(2) SQL Azure 좌절방지위원회
SQL Azure는 공유 환경에서 실행되는 클라우드 데이터베이스로, 흔히 생각하는 이상적인 클라우드 컴퓨팅 서비스보다 사실 더 엄격하고 정책적입니다. 이러한 차이점을 숙지하지 못하고 이용했을 때 벌어질 수 있는 문제점들을 진단해보고 프로그래밍 코드 상에서 개선할 점은 없는지 검토해봅니다.
- 백업을 해야할 만큼 중요한 데이터라면...
- Connection Throttling (연결 차단)에 대한 정확한 이해
- 지원되지 않는 몇 가지 옛날 기술들과 그 솔루션
- 방화벽 설정에 대한 정확한 이해
- 문자열, 시간대에 관한 주의 사항

진행 순서
- 19:00 ~ 19:50 (1) SQL Azure가 SQL Server와 다른점
- 19:50 ~ 20:00 휴식
- 20:00 ~ 20:50 (2) SQL Azure 좌절방지위원회
- 20:50 ~ 21:00 질문/답변

경품 안내

당일 추첨을 통하여 "Pro SQL Azure 입문" 도서 3권과 Microsoft Arc Wireless Keyboard 1대를 나누어드릴 예정입니다.

알립니다: 본 세미나는 커뮤니티가 주최하는 비영리 세미나이며, 당일 주차권은 별도로 제공되지 않으니 가급적 대중 교통을 이용하여 주시면 감사하겠습니다.

세미나 신청은 http://onoffmix.com/event/3671 에서 부탁드립니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2011. 8. 9. 16:21




<두번째 App Camp 진행일정>
일시 : 2011년 8월 24일(수)
시간 : 오후 7시~10시
장소 : 대치동 포스코센터 서관 5층
주의사항 : 앱 캠프는 무료로 진행되며 별도로 노트북을 제공해 드리지 않습니다. 
               참석하시는 분들은 필요한 소프트웨어를 설치한 노트북을 지참해 주십시오.

appcamp

http://blogs.msdn.com/b/eva/archive/2011/08/05/10193100.aspx

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요