페이지

2017년 12월 28일 목요일

8 옵셔널

- 옵셔널 타입
nil이 될 수도 있는 인스턴스는 반드시 옵셔널 타입으로 선언
옵셔널 타입으로 선언되지 않은 인스턴스는 nil이 되지 못한다.

- 옵셔널 바인딩
어떤 옵셔널에 값이 있는지 판단할 수 있는 유용한 패턴
if let temporaryConstant = anOptional{
      // temporaryConstant로 어떤 일을 한다
} else {
     // anOptional에는 값이 없다. 즉, anOptional은 nil이다.
}

import Cocoa

var errorCodeString: String?
errorCodeString = "404"

if let theError = errorCodeString {
   print(theError)
}

- 암묵적으로 언래핑된 옵셔널(implicitly unwrapped)

import Cocoa
var errorCodeStrig: String!
errorCodeString = "404"
print(errorCodeString)
여기서 옵셔널은 암묵적 언래핑을 나타내는 !가 붙어 선언되었다. 그리고 암묵적으로언래핑핀 오셔널을 사용한다는 것은 옵셔널을 명시적으로 언래핑하여 사용하는 것보다 훨씬 더 강한 확신, 즉 값이 있다는 확신의 방증이므로 조건문도 과감하게 없앴다.

- 옵셔널 체이닝(optional chaining)
옵셔널 바인딩처럼 어떤 옵셔널에 값이 있는지 판단

import Cocoa

var errorCodeString : String?
errorCodeString = "404"
var errorDescription: String?
if let theError = errorCodeString, let errorCodeInteger = Int(theError), errorCodeInteger == 404 {
   errorDescription = "\(errorCodeInteger + 290): resource was not found."
}

var upCaseErrorDescription = errorDescription?.uppercased()
errorDescription


- 옵셔널을 준비된 상태로 수정하기
새 변수나 상수를 만들지 않아도 되도록 옵셔널을 준비된 상태(in place)로 수정할 수도 있다. 다음처럼 upCaseErrorDescription에 append(_:) 메소드를 호출한다.

...
upCaseErrorDescription?.append( "PLEASE TRY AGAIN.")
upCaseErrorDescription

옵셔널에 값이 있을 때는 텍스트를 추가만 하면되고, 값이 없다면 할 일도 없는 것이다.

- nil 결합 연산자
옵셔널을 처리할 때는 (옵셔널에 값이 있을 때) 값을 가져오거나 옵셔널이 nil일때 기본값을 사용하는 것이 일반적이다. 이를테면 errorDescription에 담긴 오류 정보를 가져올 때 문자열에 오류가 없다면 "No error"라는 기본값을 사용할 수 있다. 이때 필요한 것이 옵셔널 바인딩이다.

let description : String
if let errorEscription = errorDescription{
   description = errorDescription
} else {
   description = "No error"
}

nil 결합 연산자 사용하기
let description = errorDescription ?? "No error"
??의 왼쪽에는 옵셔널이 와야한다.왼쪽 옵셔널이 nil이면 ??는 오른쪽 값을 리턴한다. 왼쪽 옵셔널이 nil이 아니면 옵셔널에 포함된 값이 리턴된다.



2017년 12월 26일 화요일

6. 루프

- for-in 루프

import Cocoa

var myFirstInt : Int =0

for i in 1...5 {
   myFirstInt += 1
   myFirstInt
   print(myFirstInt)
}

루프를 작성하겠다고 알리는 키워드가 for다. 그 뒤로 이터레이터 i가 선언되었는데, 루프의 현재 반복 횟수를 나타내는 이터레이터(iterator)는 루프 안에서 일정한 값을 보이며, 루프 안에서만 존재한다.

- where

for i in 1...100 where i % 3 == 0 {
   print(i)
}

타입 추론

for i in 1...5 {
   myFirstInt += 1
   print("myFirstInt equals \(myFirstInt) at iteration \(i)")
}

- while 루프

var i = 1
whle i < 6 {
  myFirstInt += 1
  print(myFirstInt)
  i += 1
}

- repeat-while 루프
repeat-while 루프는 루프를 적어도 한 번 실행하고 조건을 판단한다.

repeat{
 print("Fire blasters!")
} while shields > 0


제어권 전달문, 다시 보기

continue 사용하기

....
var shields = 5
var blastersOverheating = false
var blasterFireCount = 0
var spaceDemonsDestroyed = 0

while shields > 0 {

  if spaceDemonsDestoyed == 500 {
     print("You beat the game!")
     break
  }


 if blastersOverheating {
      print("Blasters are overheated! Cooldown initiated.")
      sleeep(5)
      print("Blasters ready to fire")
      sleep(1)
      blastersOVerheating = false
      blasterFireCount = 0
  }

  if blasterFireCount > 100 {
     blastersOverheating = true
     continue
   }

  print("Fire blasters!")
 
   blasterFireCount += 1
   spaceDemonsDestroyed += 1

}








2017년 12월 25일 월요일

5. switch

import Cocoa

var statusCode: Int = 404
var errorString: String = "The request failed:"
switch statusCode {
case 400, 401, 403, 404:
   errorString = "There was something wrong with the request."
   fallthrough
default:
   errorString += " Please review the request and try again."
}

fallthrough라는 제어권 전달문(control transfer statement)
어떤 방향으로 진행되던 실행 흐름을 바꿀 수 있다.
fallthrough 는 현재 case 가 가지고 있는 제어권을 바로 아래 case로 '전달하라'고 switch에 알린다.
다시 말해 statusCode와 일치하는 case에 fallthrough제어권 전달문이 있으면(일반적으로 case 맨 아래 fallthrough를 둠)우선 이 case 코드가 실행되고, 제어권이 현재 case를 '통과하여' 바로 아래 case로 넘어간다. 이 바로 아래 case 는 대조할 값과 일치하든 일치하지 않든 해당 코드가 ㅁ조건 실행된다.

- 구간
valueX...valueY :  대조할 값을 어떤 구간으로 설정

...라는 구간 대조(range matching)

- 값 바인딩


where

튜플과 패턴 대조
statusCode와 errorString은 논리적 연관성을 가지고 있다.
논리적 연관성을 드러낼 수 있도록 한 군데에 저장할 수 있다면 여러모로 유용할 것이다. 튜플(tuple)을 사용하는 이유가 이 때문이다.

튜플은 논리적 연관성이 있는 둘 이상의 값을 한데 묶은 일종의 유한 집합이다. 논리적 연관성의 유무를 판단하는 일은 물론 프로그래머의 몫이다. 튜플을 사용하면 서로 다른 값들이 하나의 복합 값으로 묶이는데, 묶어 놓은 결과는 순서 리스트의 구조를 보인다.


import Cocoa

var satusCode : Int =  418
var errorString: String = "The request failed with the error:"

switch statusCode {
   case 100, 101:
      errorString += " Informational, \(statusCode)."
   case 204;
      errorString += " Successful but no content, 204."
   case 300...307:
      errorString += " Redirection ,  \(statusCode)."
   case 400...417:
      errorString += " Client error, \(statusCode)."
   case 500...505:
      errorString += " Server error, \(statusCode)."
   case let unknownCode where (unknownCode >= 200 && unkonCode < 300)
                                                   ||  unKnownCode > 505:
      errorString = "\(unkownCode) is not known error code."
  default:
      errorString = "Unexpected error encountered."
}

let error = (statusCode, errorString)

튜플요소에 이름 지정하기
let error = (code: statusCode, error: errorString)
error.code
error.error

이렇게 하면 튜플 요소에 그 이름으로, 즉 statusCode는 code로 errorString은 error로 액세스할 수 있다. 오른쪽 사이드바에도 이전과 같은 결과가 출력될 것이다.

튜플을 사용하는 패턴 대조

....
let error = (code: statusCode, eorr: errorString)
error.code
error.error

let firstErrorCode = 404
let secondErrorCode = 200
let erorCodes = (firstErrorCode, secondErrorCode)
switch errorCodes{
case (404, 404):
     print("No items found.")
case (404, _):
     print("First item not found.")
case (_, 404):
     print("Second item not found.")
 default:
     print("All items found.")
}

- switch vs. if/else

.... let age = 25

if case 18...35 = age {
  print("Cool demographic")
}


여러 조건이 담긴 if-case
...
let age = 25
if case 18...35 = age, age >=21 {
    print("In cool demographic and of drinking age")
}





인공지능 레벨4

레벨1: 단순한 제어 프로그램을 '인공지능'이라고 칭하고 있다.
마케팅적으로 '인공지능'즉 'AI'라고 지칭하는 것이며, 지극히 단순한 제어 프로그램을 탑재하고 있는 전자 제품을 '인공지능 탑재' 등이라고 부르는 경우

레벨2: 고전적인 인공지능:
행동의 패턴이 지극히 다채로운 경우에서의 지능을 말한다. 장기 프로그램이나 청소 로봇 혹은 질문에 대답하는 인공지능 등이 이에 해당된다.

레벨3: 기계학습을 받아들인 인공지능:
검색 엔진에 내장되어 있거나 빅데이터를 바탕으로 자동적으로 판단하는 인공지능이다.
추론의 구조나 지식 베이스가 데이터를 바탕으로 학습하는 것으로 전형적으로 기계학습의 알로리즘이 이용되는 경우가 많다. 기계학습이라는 것은 표본이 되는데이터를 바탕으로 규칙이나 지식을 스스로 학습하는 것이다. 이 기술은 패턴 인식이라는 과거부터의 연구를 기초로 1990년대부터 진행되어 2000년대에 들어와 빅데이터 시대를 맞이하면서 더욱 진화하고 있다.

레벨4: 딥러닝을 받아들인 인공지능
기계학습을 할 때의 데이터를 나타내기 위해서 사용되는 입력값input(특징feature 이라고 불린다) 자체를 학습하는 것이 이

2017년 12월 23일 토요일

4장. 수

4.1. 정수
macOS에서 Int 는 64비트
iOS 에서 아이폰 5s, 아이패드 에어, 아이패드 미니 레티나 디스플레이브터 64비트 채용
그전 기기들에서는 32비트 아키텍처가 적용

스위프트에서는 크기를 분명하게 밝힌 정수 타입도 제공, Int32 는 32비트 부호 있는 정수 타입니다.

Int32, Int8, Int64, UInt, UInt16, ..., UInt64

- 정수의 연산

- 다른 정수 타입으로 전환하기

- 부동소수점수(floating-point number)
32비트 부동소수저민 Float 와 64비트 부동소수점인 Double

2017년 12월 22일 금요일

2. Swift 프로그래밍 기초

2.1. Xcode 에서 Swift 프로젝트 작성 및 플레이그라운드

- Foundation
프로그램 개발에 꼭 필요하고 기본이 되는 프레임워크
문자, 스트링, 숫자, 메모리 관리 등 프로그래밍 시 사용되는 기본 기능 포함.

import Foundation

2.2. Swift 기본 데이터형

Int, Float, Double, Character, Bool

2.3. 사칙연산 처리

2.4. 반복문 - while 문장

2.5. 반복문 - for 문장

2.6. if 문장, switch 문장

2.7. 문자열 배열

2.8. 숫자 배열

2.9. 딕셔너리(Dictionary)

2.10. 함수 생성 및 호출

2.11. 옵셔널(Optionals)기능

2.12. 클래스 생성 및 초기화


제 3절 클라우드 인프라 기술

클라우드 컴퓨팅은 동적으로 확장할 수 있는 가상화 자원들을 인테넷으로 서비스할 수 있는 기술
클라우드 서비스 유형
-SaaS(Software as a Service)
-PaaS(Platform as a Service)
-IaaS(Infrastructure as a Service)

VMware나 Xen과 같은 서버 가상화 기술은 데이터센터나 기업들에게 인프라스크럭처를 위한 클라우드 서비스의 가능성을 보여주고 있다.

아마존 S3(Simple Storate Service), EC2(Elastic Cloud Computing) 화녁을 제공함으로써 플랫폼을 위한 클라우드 서비스를 최초로 실현
구글 AppEngine, Apps, Gears, Gadgets 등을 제공함으로써 휍기반의 다양한 소프트웨어들이 클라우드 서비스로서 구체화

서버 가상화 기술: 물리적인 서버와 운영체제 사이에 적절한 계층을 추가해 서버를 사용하는 사용자에게 물리적인 자원은 숨기고 논리적인 자원만을 보여주는 기술
여러개의 애플리케이션, 미들웨어, 운영체제들이 서로 영향을 미치지 않으면서 동시에 사용할 수 있음.

서버 가상화 기술 효과
- 가상머신 사이의 데이터 보호
- 예측하지 못한 장애로부터 보호
- 공유 자원에 대한 강제 사용의 거부
- 서버 통합
- 자원 할당에 대한 증가된 유연성
- 테스팅
- 정확하고 안전한 서버 사이징
- 시스템 관리

가. CPU 가상화
하이퍼바이저(Hypervisor)는 물리적 서버 위에 존재하는 가상화 레이어를 통해 운영체제가 수행하는데 필요한 하드웨어 환경을 가상으로만들어 준다. 엄격하게 구분할 경우에는 차이가 있지만, 일반적으로 가상머신(Virtual machine)을 하이퍼바이저라고 할 수 있다. 하이퍼바이저가 서버 가상화 기술의 핵심으로 x86계열 서버 가상화에서는 소프트웨어 기반으로 하이퍼바이저를 구성한다. 하이퍼바이저를 통해 사용자는 추가 하드웨어 구입 없이 새로운 운영체제의 설치, 애플리케이션의 테스팅 및 업그레이드를 동일한 물리적 서버에서 동시에 수행할 수 있다.
하이퍼바이저는 VMM(Virtual Machine Monitor)이라고도 하며, 다음과 같은 기능을 수행

- 하드웨어 환경 에뮬레이션(Emulates a complete hardware environment)
- 실행환경 결리(Isolate execution in each VM)
- 시스템 자원 할당(Allocates platform resources-processing, memory, I/O, storage)
- 소프트웨어 스택 보존(Encapsulates software stacks including the OS and state information)

가상화를 제공하는 하이퍼바이저가 물리적인 하드웨어 또는 호스트 운영체제와의 관계에서 어디에서 위치하는지에 따라 베어메탈(Bare-metal) 하이퍼바이저와 호스트 기반(Hosted) 하이퍼바이저로 나뉠수 있다.

베어메탈 하이퍼바이저
반가상화(Para Virtualization), 완전가상화(Full Virtualization)

가상 머신 내에서도 운영체제가 필요하고 이 운영체제는 Ring 0 의 권한을 필요하게 된다. 가상머신의 운영체제가 응용 애플리케이션 권한(Ring 3)으로 수행될 경우 x86아키텍처에서는 복잡한 문제가 발생한다. Ring 3에서 수행된 가상머신 운영체제에서 Ring 0 수준의 명령을 호출하면 가상화를 지원하는 계층에서 이를 Ring 0 수준의 명령어도 다시 변환해 실행해야 하ㅕ, 이를 위해 가상화 지원 계층은 받으시 Ring 0 레벨(Intel VT-x, AMD-V에서는 Ring -1)로 수행되어야 한다.
x86 아키텍처에서 가상화 기술의 핵심은 가상머신이 요청하는 privileged 명령어를 어떻게, 어떤 계층에서 처리 하느냐이다. 가상화의 용어 중 완전가상화(Full Virtualization), 반가상화(Para Virtualization)라는 용어도 privileged 명령어를 어떻게 처리하느냐를 기준으로 분류한 것이다.


- 완전가상화
완전가상화(Full Virtualization)는 CPU뿐만 아니라 메모리, 네트워크 장치 등 모든 자원을 하이퍼바이저가 직접 제어.관리하기 때문에 어떤 운영체제라도 수정하지 않고 설치가 가능한 장점이 있다. 하지만 하이퍼바이저가 자원을 직접 제어하기 때문에 성능에 영향을 미친다. 또한 자원들이 하이퍼바이저에 너무 밀접하게 연관돼있어 운영중인 게스트 운영체제에 할당된 CPU나 메모리 등의 자원에 대한 동작변경 작업이 단일 서버 내에서는 어렵다. 자원에 대한 동적변경을 하기 위해서는 VMware의 VMotion과 같은 솔루션의 도움을 받아야 한다.

완전가상와는 하이퍼바이저보다 우선쉰위가 낮은 가상머신에서는 실행되지 않는 privileged 명령어에 대해서 trap을 발생시켜 하이퍼바이저에서 실행하는 방식으로, MS 원도우와 같은 Guest OS가 하이퍼바이저상에서 변경되지 않은 상태로 실행될 수 있는 장점이 있으나 Para Virtualization에 비해 속도가 느리다. VMware ESX Server, MS Virtual Server 등의 제품이 완전 가상화 기반 솔루션이다.
초기 Xen에서는 완전가상화를 지원하지 않았지만, 최근 Intel VT, AMD-V환경에서 완전가상화를 지원하고 있다.

-하드웨어 지원 완전가상화
Intel VT-x, AMD-V CPU의 하드웨어에서제공하는 가상화 기능을 이용
가상머신에서 메모리와 CPU등의 하드웨어에 명령을 내릴 수 있는 반가상화 수준의 성능 발휘

CPU 에 Ring -1 계층이 추가
하이퍼바이저는 Ring -1에서 수행 가상머신 운영체제(Guest OS)는 Ring 0 에서 수행되어 privileged 명령어에 대해 추가로 변환 과정이 필요 없다.
하이퍼바이저를 거쳐 바로 하드웨어로 명령이 전달돼 빠른 성능 보장

하드웨어 지원 가상화를 사용하는 경우 CPU 사용률이 폰아진다. 특히 I/O나 메모리를 많이 사용하는 경우 CPU 사용률이 높아진다. 따라서 서버 통합을 목적으로 하는 경우 비효율적 있수도 있다.


- 반가상화
반가상화(Para Virtualization)는 privileged명령어를 게스트 운영제에서 hypercall로 하이퍼바이저에 전달하고, 하이퍼바이저는 hypercall에 대해서 privilege레벨에 상관없이 하드웨어로 명령을 수행시킨다.
Hypercall은 게스트 운영체제에서 요청을 하면 하이퍼바이저에서 바로 하드웨어 명령을 실행하는 call 을 말한다.
게스트 운영체제가 hypercall을 요청하기 위해서는 케스트 운영체제의 일부분이 수정 되어야 하며, Xen 기반의 리눅스 운영체제의 경우 20% 정도 커널이 수정되었다고 한다. 수정된 게스트운영체제는 CPU나 메모리와 같은 자원에 대한 직접적인 제어권을 가짐으로써 자원의 변화와 같은 동적 가상화 환경에 유연하게 적응할 수 있다. 따라서 반가상화 기반에서는 CPU와 메로리 자원의 동적 변경이 서비스의 중단 없이 이루어질 수 있으며, 완전가상화에 대해 성능이 뛰어나다. 반가상화는 privileged명령어를 직접 호출(hypercall)하므로 속도는 빠르나 커널을 변경해야 하고, 완전가상화는 dynamic binary translation(Xen은 emulation)모듈과의 통신을 통해 처리하므로 속도는 느리나 커널 변경이 없다. Vmware와 같은 상용 솔루션은 완전가상화와 반가상화의 장단잠을 보완해 아키텍처, 기능, 성능 등에서 뚜렷한 차이가 없다.
기존 VMware에서는 반가항화를 지원하지 않았지만 VMI(Virtual Machin Interface)라는 인터페이스를 제시하고, 이 인터페이스를 준수하는 모든 게스트 운영체제를 지원하는 방식으로 반가상화를 지원하고있다. VMI는 아직 정식 표준으로 채택되지 않았지만 리눅스 진영에서도 도입하려는 움직임이 나타나고 있다.

- Monolithinc vs. Microkernel
하드웨어에 대한 드라이버가 어느 계층에 있느냐에 따라 Monolithinc 방식과 Microkernel방식으로 구분
가상머신이 I/O를 위해 하드웨어에 접근할 때 사용하는 드라이버를 하이퍼바이저 계층에서 모두 갖고 있는 방식을 Monolithic이라고 한다.
각 가상머신에서 드라이버를 갖는 방식을 Microkernel이라고한다.
__________________________________________________________________________
그림은VMware의 경우 하이퍼바이저가 드라이버를 작고 있으며 모든 I/O 요청은 하이퍼바이저가 수행함을 보여준다.
Xen에서 하이퍼바이저는 드라이버가 없으며 호스트 운영체제가 드라이버를 가지고 있고 각 게스트 운영체제는 가상 드라이버를 가지고 있어 I/O 요청을 위해서는 호스트 운영체제를 거쳐야 한다. 게스트와 호스트 운영체제는 서로 격리되어 있기 때문에 하이퍼바이저(또는 VMBus)를 이요해 요청을 주고 받는다.

Monolithin 방식은 성능은 조금 향상될 수 있지만 하이퍼바이저에서 모든 드라이버를 가기ㅗ 있어야 하기 때문에 하드웨어가 추가되거나 드라이버가 업데이트 되는 경우 하이퍼바이저가 수정되어야 하고 더 많은 코드를 가지고 있기 때문에 장애가 발생할 가능성도 높다. Microkernel 방식의 경우 속도는 조금 느려지지만 하이퍼바이저 계층이 간단하여 드라이버 업데이트나 하드웨어 추가에 따른 하이퍼바이저 변경이 필요없으며, 장애 발생 확률이 훨씬 낮다.

하이퍼바이저 기반 가상화 기술비교
구분                     완전가상화                   완전가상화                    반가상화
                     (CPU 기술 이용 안함)     (CPU 기술 이용)
사용기술       바이너리 변환, Direct   Privileged Instruction은    수정된 OS 사용
                          Execution                   Ring -1로 처리됨
게스트 OS      게스트 OS 변경 없음,    게스트 OS 변경이 필요     Hypercall을 가능하도록
변경/호환성      호환성이 뛰어남            없음/호환성 뛰어남          게스트 OS 변경함/
                                                         (단 CPU가 지원해야 함)       호환성이 안 좋음
성능                                                    Fair(점점 Binary        
                            좋음                   Translation 방식의 성능에      특정 경우에 더 좋음
                                                             근접해 가고 있음)
제품             VMware, Microsoft,     VMware, Microsoft,         VMware, Xen
                        Parallels                     Parallels, Xen
게스트 OS가      독립적임                       독립적임                   Xen Para Virtualization은
하이퍼바이저에                                                                     Xen 하이퍼바이저에서만 동작,
독립적인가?                                                                                 VMI 규격을 따르는
                                                                                           VMI-Linux는 하이퍼바이저에
                                                                                                   독립적임

-호스트 기반 가상화(Host based virtualization)
완전한 운영체제가 설치되고 가상화를 담당하는 하이퍼바이저가 호스트 운영체제 위에 탑재되는 방식이다. 다른 가항화 환경에 비해 성능은 물론 자원 관리 능력 측면에서도 제약 사항이 많은 편이다. 가장 큰 단점은 단일 운영체제의 취약성에 있다. 예를 들어 호스트 운영체제 레벨에서 보안 이슈가 발생할 경우 전체 게스트 운영체제의 신뢰성에도 문제가 발생할 수 있다. 호스트 기반가상화의 대표 사례로는 VMware, Workstation, Microsoft Virtual PC 등이 있다.

______________________________________________________________________
주로 테스트 환경에서 많이 사용되었으며 최근에는 맣이 사용하지 않는다, 하지만 기존 레거시 애플리케이션 중 아주 오래된 하드웨어와 그 하드웨어를 지원하는 특정 운영체제에서만 수행되어야 하는 애플리케이션을 가상화 기반에서 운영하는 경우에 사용할 수 있다.

-컨테이너 기반 가상화(Container based virtualization)
호스트 운영체제 위에 가상의 운영체제를 구성하기 위한 운영 환경 계층을 추가하여 운영체제만을 가상화한 방식.
운영체제만을 가상화 대상으로 하므로 전체 하드웨어를 대상으로 하는 하이퍼바이저 기반 가상화 방식에 비해 훨씬 적게 가상화 한다. 결과적으로 한 대의 서버에서 더 많은 컨테이너를 실행할 수 있다. 컨테이너 기반 가상화 방식에서 가상화를 지원하는 계층을 하이퍼바이저라고 하지 않으며, 가상 운영환경(Virtual server enviroment)라고 부른다.

컨테이너 기반 가상화는 가상화 수준이 낮기 때문에 다른 방식에 비해 빠른 성능을 보여주지만, 자원간 격리 수준이 낮아 하나의 가상 운영체제에서 실행되는 애플리케이션의 자원 사용에 따라 다른 가상 운영체제가 영향을 받는 단점이 있다.
또한 호스트 운영체제의 보안 취약성에 의해 모든 가상 운영체제에 문제가 발생할 수 이으며, 호스트 운영체제를 공유하기 때문에 호스트 운영체제의 문제가 전ㅊ 가상 운영체제에서도 영향을 미치게 된다.
컨테이너 기반 가상화는 오픈소스 진영의 OpenVZ와, OpenVZ를 사용화한 Virtuozzo, Solaris Containers, Linux-VServer등

하이퍼바이저 기반 가상화와 컨테이너 기반 가상화 비교

구분                      하이퍼바이전 기반(Full, Para)                    컨테이너 기반
하드웨어 독립성    가상머신 내에서 완전 독립                           호스트 OS사용
OS 독립성             호스트 OS와 완전 독립(리눅스와 원도우    호스트와 게스트 동일
                                   머신 동시 사용)
격리수준               높은 격리 수준                                           낮은 격리 수준
성능                      높은 오버헤드 발생                                     오버헤드 거의 없음,
                             성능 향상을 위해 HW 가상화 기술 병행      HW 자원의 대부분을 활용
관리                      가상머신 별로 별도 관리                            공통 SW 중앙 집중식 관리
응용분야               이기종 통합(윈도우와 리눅스 혼합 환경)     단일 OS환경 자원 통합,
                                                                                              대규모 호스팅 업체
대표제품              VMware ESX, MS Virtual Server              Virtuozzon(상용, OpenVZ-공개)
                            Xen(Para Virtualization)                          Sun Solaris Container


나. 메모리 가상화(VMware기법)
운영체제는 메모리를 관리하기 위해 물리주소(Physical Address)와 가상주소(Virtual Address), 이 두가지를 사용
물리주소는 0부터 시작해서 실제 물리적인 메모리 크기까지를 나타내고, 가상주소는 하나의 프로세스가 가리킬 수 있는 최대 크기를 의미하며 32비트 운영체제에서는 4GB까지 사용가능
프로그램에서의 주소는 물리적인 메모리의 주소 값이 아닌 가상주소 값이다.
따라서 가상주소 값의 위치(VPN, Virtual Page Number)를 실제 물리적인 주소 값 위치(MPN, Machine Page Number)로 매핑 과정이 필요하며 page table을 이용 매핑 연산을 하드웨어적으로 도와주는 것을 TLB(Translation lookaside buffer)라고 한다.
VMware의 하이퍼바이저의 핵심 모듈을 VMKernel이라고 한다. VMkernel은 Service Console, 디바이스 드라이버들의 메모리 영역을 제외한 나머지 전체 메모리 영역을 모두 관리하면서 가상머신에 메모리를 할당한다. 생성되는 가상머신은 자신에게 할당되 메모리들을 연속된 공간의 실제 물리적인 메모리로 인식하게 된다.

VMware는 하이퍼바이저 내에 Shadow Page Table을 별도로 두어 가상 메모리 주소와 물리 메모리 주소의 중간 변환 과정을 가로챈다. 이 테이블은 마치 연속된 빈 공간의 메모리가 실제 존재하는 것처럼 게스트 운영체제에서 매핑해주는 역할을 하며, 동시에 개발적인 모든 가성머신들이 자신만의 메모리 주소 공간을 갖도록 한다.

- Memory ballooning
 VMKernel은 예약된 메모리보다 더 많은 메모리를 사용하는 가상머신의 메모리 영역을 빈 값으로 강제로 채워 가상머신 운영체제가 자체적으로 swapping하도록 한다. 가상머신 운영체제에서 보이는 물리적인 메모리(실제는 하이퍼바이저에서 제공한 논리적 메모리)가 채워지고 있다는  것을 감지한 가상머신 운영체제는 swap파일에 메모리 영역을 page out 시키고 메모리를 비우게 된다. 하이퍼바이저는  page out 된 메모리 영역을 다른 가상머신에 할당한다.

- Transparent page sharing
하나의 물리적인 머신에 여러 개의 가상머신이 운영되는 경우 각 가상머신에 할당된 메모리 중 동일한 내용을 담고 있는 페이지는 물리적인 메모리 영역에 하나만 존재시키고 모든 가상머신이 공유하도록 한다.

- Memory Overcommitment
2GB 메모리를 가진 물리적 장비에 512MB를 Minimum reserved를 가질 수 있는 가상머신 5개를 수행할 수 있다. 이것은 앞서 설명한 두 가지 기법을 이용하여 가능하지만, 모든 가상머신이 메모리 사용이 많은 업무를 수행하는 경우라면 심각한 성능저하 현상이 발생할 수 있기 때문에 권장하지 않는다.

다. I/O 가상화
-가상 이더넷
대표적인 I/O 가상화 기술의 하나로 가상화 기능 중에서 물리적으로 존재하지 않는 자원을 만들어 내는 에뮬레이션 기능을 이용한다. 가상 이더넷을 이용할 경우 각 가상 머신들 사이에 물리적인 네트워크 어댑터 없이도 메모리 버스를 통해 고속 및 고효율 통신이 가능하다.
또한 가상 이더넷은 가상 LAN 기술을 기반으로 네트워크 파티션도 가능하게 한다. 하나의서버에 4개의 가상머신을 구성하는 경우 2개의 가상머신을 묶어 가상 LAN으로 구성하면, 각 가상 LAN 사이에는 통신을 할 수 없게 된다. 이처럼 가상 이더넷을 통해 사용자들은 별도의 물리적 어댑터와 케이블을 사ㅛㅇ하지 않고 네트워크의 이중화, 네트워크의 안정적 단절 등의 효과를 얻을 수 있다.

-공유 이더넷 어댑터
여러 갱의 가성머신이 물리적인 네트워크 카드를 공유할 수 있게 하며, 공유된 물리적 카드를 통해서 외부 네트워크와 통신이 가능하다. 특히 가상머신의 개수보다 물리적 ㄷ어대버의 개수가 적은 경우에 여러 가상머신들이 물리적 이더넷 어댑터를 공유할 수 있게 해 준다. 이 경우에도 하나의 자원을 이용하여 여러 가상머신이 공유하기 때문에 발생하는 병목현상은 피할 수 없다.


-가상 디스크 어댑터
한 대의 서버가 여러 개의 가상머신을 구성할 경우 가장 문제가 되는 부분이 외장 디스크를 사용할 수 있게 해주는 파이버 채널 어댑터(Fiber Channel Adapter)와 같은 I/O 어댑터의 부족이다. 이를 해결하기 위해 가상 디스크 어댑터의 개념이 필요하다.
가상회된 환경에서 가상 디스크를 이용해 가상머신이 디스크 자원을 획득하는 방법에는 두 가지가 있다. 먼저 내장 디스크의 경우 가상 I/O 레이어가 내장 디스크들을 소유하고 있다, 이 내장 디스크들을 논리적 디스크 드라이브로 나눈다. 논리적으로 나누어진 드라이버는 LUN(Logical Init Number)으로 각 파티션에 가상 디스크 어댑터를 통해 분배된다. 해당 가성머신은 이렇게 획득한 논리적 디스크 자원을 물리적 자원처럼 인식한다.
두 번째로 외장 디스크의 경우 먼저 가상 I/O 레이어가 파이버 채널 어댑터를 통해서 외장 디스크의  LUN을 획득한다. 그리고 내장 디스크와는 달리 가상  I/O 레이어가 이 자원을 논리적 디스크 드라이브로 다시 나누지 않고 바로 각 가상머신에 가상 디스크 어댑터를 통해서 분배한다 이처럼 가상 I/O레이어를 통해 제공된 논리적 디스크 볼륨은 이를 이용하는 다른  가상머신에게는 SSCSI 디스크로 나타난다.