# 오픈스택 인 액션 <sub>상용 수준의 자체 클라우드를 구축하는 단계별 지침</sub>
## 챕터 1. 오픈스택 소개
강력하고 저렴한 범용 하드웨어<sub>x86</sub> 등장했고, 이러한 범용 하드웨어를 클라우드화<sub>(자원의 집합으로 추상화하여 관리하는 것)</sub>할 수 있게 해주는 도구가 필요해졌다.
오픈스택은 웹 기반 인터페이스, CLI, API로 관리할 수 있다.
오픈스택은 AWS와 동일한 수준의 조직화된 효율을 제공하는 것을 목표로 하고 있다.
### 1.1 오픈스택이란?
오픈스택은 클라우드 운영체제이며, 다음과 같은 것을 할 수 있다.
- 물리 및 가상 서버, 네트워크 스토리지 시스템의 자원을 엮어서 이용할 수 있다.
- 테넌트, 할당량<sub>quota</sub>, 사용자 역할<sub>user role</sub>을 통해 자원의 클라우드를 효과적으로 관리할 수 있다.
- 공통 인터페이스를 제공하여 하부 제조사 서브시스템과 관계없이 자원을 제어할 수 있다.
##### 테넌트
논리적으로 서로 격리된 VM들이 사용하는, 할당량을 제한한 자원의 집합을 의미한다.
### 1.2 클라우드 컴퓨팅과 오픈스택 이해하기
사설 클라우드란 기업이 보유하고 관리하는 인프라 자원(VM, 스토리지 등)의 모음, 즉 IaaS라고 설명할 수 있다.
이 책의 목표는 독자들의 회사에 공용 클라우드<sub>AWS, Azure 등</sub>에서와 같은 편의성과 효율성을 제공하는 것이다.
##### 다중 테넌시
부서별로 컴퓨팅 자원들을 관리할 수 있는 클라우드 플랫폼의 능력을 의미한다.
##### 하이브리드 클라우드
업무상 필요에 의해 사설과 공용 클라우드 둘 다를 이용하는 경우, 이러한 조합을 하이브리드 클라우드라고 부른다.
보안 유지가 목적이라면 대개 사설 클라우드를 사용하고, 전 세계를 대상으로 하여 한 기업이 부담하기에는 과도한 비용이 드는 작업에는 일반적으로 공용 클라우드를 사용한다.
#### 1.2.1 추상화와 오픈스택 API
- **하드웨어와 소프트웨어 자원의 추상화** - 특정 구성요소가 제조사에 족송되는 것을 피할 수 있다.
- **자원들 간의 공통 API** - 연결된 구성요소들의 완전한 오케스트레이션이 가능하다.
### 1.3 오픈스택과 오픈스택이 제어하는 컴퓨터 자원과의 관계
#### 1.3.1 오픈스택과 하이퍼바이저
- 하이퍼바이저는 가상 머신을 위해 물리 하드웨어를 에뮬레이션하는 소프트웨어다.
- **오픈스택 자체는 하이퍼바이저가 아니며 단지 하이퍼바이저의 동작을 제어할 뿐이다.**
- 오픈스택은 젠서버<sub>XenServer</sub>/XCP, KVM<sub>Kernel-based Virtual Machine</sub>, QEMU, LXC, ESXi, VMware ESXi, 마이크로소프트 Hyper-V 등의 다양한 하이퍼바이저를 지원한다.
이 책의 예제에서는 KVM을 사용할 것이다.
#### 1.3.2 오픈스택과 네트워크 서비스
오픈스택 자체는 가상 스위치가 아니지만 여러 물리 및 가상 네트워크 장치와 가상 오버레이 네트워크를 관리할 수 있다.
DHCP나 라우팅 등의 네트워크 서비스는 오픈스택이 직접 제공한다.
#### 1.3.3 오픈스택과 스토리지
일반적인 스토리지의 개념에서 볼 때 오픈스택 자체는 스토리지 어레이가 아니다. 오픈스택은 가상 머신이 사용하는 스토리지를 물리적으로 제공하지는 않는다.
##### 블록 스토리지
블록 스토리지는 운영체제나 파일 시스템이 주로 사용한다.
##### 오브젝트 기반 스토리지
일반적으로 소프트웨어 API를 통해 접근할 수 있다. 파일과 블록 스토리지를 한 단계 더 추상화한 것이다.
오브젝트 스토리지에서는 블록 스토리지보다 더 긴 지연 시간이 허용되기 때문에 VM의 볼륨으로는 사용되지 않고, 볼륨과 이미지의 백업을 저장하기 위해 일반적으로 사용한다.
#### 1.3.4 오픈스택과 클라우드 용어
- IaaS - 개별 가상 머신을 직접 프로비저닝하고 관리할 수 있다.
- PaaS - 애플리케이션 오케스트레이션 기능에 대한 접근만 가능하다.
- SaaS - IaaS 또는 PaaS를 사용하는 고객에게 특정 서비스를 제공한다.
### 1.4 오픈스택 구성요소 소개
다음은 오픈스택을 구성하는 기본적인 구성요소들이다.
| 프로젝트 | 코드명 | 설명 |
|--------|------|-----|
| 컴퓨트 | 노바<sub>nova</sub> | CPU, 메모리, 디스크, 네트워크 인터페이스 등의 VM 자원 관리 |
| 네트워크 | 뉴트론<sub>Neotron</sub> | IP 주소, 라우팅, SDN<sub>Software Defined Network</sub> 등 VM의 네트워크 인터페이스가 사용하는 자원 제공 |
| 오브젝트 스토리지 | 스위프트<sub>Swift</sub> | RESTful API로 접근할 수 있는 오브젝트 스토리지 제공 |
| 블록 스토리지 | 신더<sub>Cinder</sub> | VM에 블록 스토리지(일반적인 디스크) 제공 |
| 아이덴티티 | 키스톤<sub>Keystone</sub> | 오픈스택 구성요소를 위한 역할 기반 접근 제어<sub>Role-Based Access Control, RBAC</sub> 관리 및 인증 서비스 제공 |
| 이미지 서비스 | 글랜스<sub>Glance</sub> | VM의 디스크 이미지 관리, VM에 이미지 제공 및 스냅샷(백업) 서비스 제공 |
| 대시보드 | 호라이즌<sub>Horizon</sub> | 오픈스택에서 작업하기 위한 웹 기반 GUI 제공 |
| 텔레메트리 | 실로미터<sub>Ceilometer</sub> | 오픈스택 구성요소의 사용량 측정 및 모니터링을 위한 도구 모음 제공 |
| 오케스트레이션 | 히트<sub>Heat</sub> | 오픈스택 환경을 위한 템플릿 기반의 클라우드 애플리케이션을 오케스트레이션하는 기능 제공 |
### 1.5 오픈스택의 역사
오픈스택은 6개월 주기로 새 버전을 발표해오고 있다. https://releases.openstack.org/
### 1.6 요약
- IaaS 클라우드는 관리 프레임워크를 통해 조율되는 범용 자원의 모음이다.
- 오픈스택은 최종 사용자가 직접 IaaS를 조정하고 애플리케이션을 오케스트레이션(PaaS/SaaS)할 수 있도록 해주는 관리 프레임워크다.
- 오픈스택은 하이퍼바이저, 스토리지 시스템, 네트워크 하드웨어와 소프트웨어 등 기존 상용 및 커뮤니티 기술을 제어한다.
- 오픈스택은 각각 특정 목적을 가진 프로젝트의 모음으로 구성된다.
- 오픈스택의 각 프로젝트는 고유한 코드명을 가지고 있다.
## 챕터 2. 오픈스택 맛보기
간편한 오픈스택 배포 도구인 **데브스택**을 사용하여 오픈스택을 체험해보자.
데브스택을 사용하면 대규모 배포 환경 대신에 작은 큐모로 배포된 오픈스택을 사용해볼 수 있다.
### 2.1 데브스택이란 무엇인가?
데브스택은 환경을 준비하고 오픈스택을 구성하기 위하여 배포하기 위해 사용하는 배시 셸 스크립트의 모음이다.
### 2.2 데브스택 배포하기
데브스택이 배포된 오픈스택 인스턴스가 들어 있는 컴패니언 VM을 제공한다.
#### 2.2.1 서버 생성하기
우분투 14.04를 권장한다.
#### 2.2.2 서버 환경 준비하기
```bash=
# 패키지 갱신하기
sudo apt-get -y update
# 패키지 업그레이드하기
sudo apt-get -y upgrade
# 깃 설치하기
sudo apt-get -y install git
```
#### 2.2.3 데브스택 준비하기
**주의** : Krane VM 환경에서는 아래 환경변수를 먼저 설정해주세요. (user를 변경할 때마다)
```bash=
export http_proxy=http://proxy.daumkakao.io:3128
export HTTP_PROXY=$http_proxy
export https_proxy=$http_proxy
export HTTPS_PROXY=$http_proxy
export HOST_IP=$(hostname -i)
export no_proxy=localhost,127.0.0.1,127.0.0.0/8,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,.daumkakao.io,.daumcorp.com,.daum.net,.kakao.com,.iwilab.com,.daumkakao.com,.dakao.io,.9rum.cc,daumkakao.io,daumcorp.com,daum.net,kakao.com,iwilab.com,daumkakao.com,dakao.io,9rum.cc,$HOST_IP
export NO_PROXY=$no_proxy
```
```bash=
# 데브스택 스크립트 가져오기
sudo git clone https://github.com/openstack-dev/devstack.git /opt/devstack/
```
```bash=
# 데브스택 디렉터리 준비하기
sudo chmod u+x tools/create-stack-user.sh
sudo tools/create-stack-user.sh
sudo chown -R stack:stack /opt/devstack/
```
### 2.2.4 데브스택 실행하기
```bash=
# stack 사용자로 전환하고 /opt/devstack/ 디렉터리로 이동하기
sudo -i -u stack
cd /opt/devstack/
# Krane VM 내에서 stack 유저로 변경하려고 하면 패스워드가 필요하기 때문에
# 아래 방법으로 대체하였습니다.
sudo -i
sudo -i -u stack #
cd /opt/devstack/
```
```bash=
# vim 편집기로 local.conf 생성하기
vim local.conf
```
```text
[[local|localrc]]
# Credentials
ADMIN_PASSWORD=devstack
MYSQL_PASSWORD=devstack
RABBIT_PASSWORD=devstack
SERVICE_PASSWORD=devstack
SERVICE_TOKEN=token
# Enable/Disable Services
disable_service n-net
enable_service q-svc
enable_service q-agt
enable_service q-dhcp
enable_service q-13
enable_service q-meta
enable_service neutron
enable_service tempest
HOST_IP=10.0.2.32
# NEUTRON CONFIG
#Q_USE_DEBUG_COMMAND=True
# CINDER CONFIG
VOLUME_BACKING_FILE_SIZE=102400M
# GENERAL_CONFIG
API_RATE_LIMIT=False
# Output
LOGFILE=/opt/stack/logs/stack.sh.log
VERBOSE=True
LOG_COLOR=False
SCREEN_LOGDIR=/opt/stack/logs
```
```bash=
# 스태킹하기
./stack.sh
```
스태킹이 시작되고 10분쯤 지났을 때, 뉴트론 설치 과정에서 아래 오류와 함께 실패한다.
```text
[ERROR] /opt/devstack/lib/neutron_plugins/ovn_agent:349 The q-agt/neutron-agt service must be disabled with OVN.
```
`local.conf`에서 `enable_service q-agt`를 `disable_service q-agt`로 수정하고 재시도하면 수십 분 후 아래와 같은 메시지를 출력하며 프로그램이 종료된다.
```text
...
exit_trap: cleaning up child processes
+ ./stack.sh:exit_trap:529 : kill 123699
+ ./stack.sh:exit_trap:533 : '[' -f /tmp/tmp.lGPlBR2rc4 ']'
+ ./stack.sh:exit_trap:534 : rm /tmp/tmp.lGPlBR2rc4
+ ./stack.sh:exit_trap:538 : kill_spinner
+ ./stack.sh:kill_spinner:433 : '[' '!' -z '' ']'
+ ./stack.sh:exit_trap:540 : [[ 1 -ne 0 ]]
+ ./stack.sh:exit_trap:541 : echo 'Error on exit'
Error on exit
+ ./stack.sh:exit_trap:543 : type -p generate-subunit
+ ./stack.sh:exit_trap:544 : generate-subunit 1653265384 1040 fail
+ ./stack.sh:exit_trap:546 : [[ -z /opt/stack/logs ]]
+ ./stack.sh:exit_trap:549 : /usr/bin/python3.8 /opt/devstack/tools/worlddump.py -d /opt/stack/logs
+ ./stack.sh:exit_trap:558 : exit 1
```
`run_tests.sh` 파일을 실행시켰을 때 아래와 같이 테스트에 통과하는 것 같다.
```text
...
OK
=====================================================================
PASS tests/test_functions.sh
PASS tests/test_ini_config.sh
PASS tests/test_ip.sh
PASS tests/test_libs_from_pypi.sh
PASS tests/test_localconf.sh
PASS tests/test_meta_config.sh
PASS tests/test_package_ordering.sh
PASS tests/test_refs.sh
PASS tests/test_truefalse.sh
PASS tests/test_vercmp.sh
PASS tests/test_worlddump.sh
PASS tests/test_write_devstack_local_conf_role.sh
=====================================================================
```
### 2.3 오픈스택 대시보드 사용하기
#### 2.3.1 [Overview] 화면
컴퓨트, 네트워크, 오브젝트 스토리지, 오케스트레이션 등을 관리할 수 있는 여러 영역으로 구분되어 있다.
#### 2.3.2 [Acess & Security] 화면
보안 담당자에게 중요한 화면이다.
#### 2.3.3 [Images & Snapshots] 화면
#### 2.3.4 [Volumes] 화면
#### 2.3.5 [Instances] 화면
### 2.4 첫 번째 사설 클라우드 서버에 접속하기
#### 2.4.1 인스턴스에 유동 IP 할당하기
#### 2.4.2 유동 IP에 네트워크 트래픽 허용하기
### 2.5 요약
- 오픈스택은 분산 클러우드 프레임워크지만 모든 구성요소를 단일 서버에 설치할 수 있다.
- 데브스택은 한 대 이상의 서버에 오픈스택의 개발용 인스턴스를 배포하기 위해 사용할 수 있는 스크립트의 모음이다.
- 데브스택을 통한 구성요소 배포는 중앙의 구성 파일에서 제어한다.
- 데브스택 배포 환경을 테스트하기 위해 데브스택 엑서사이즈나 데브스택 템페스트를 사용할 수 있다.
- 오픈스택은 웹 기반의 대시보드, 명령줄 인터페이스, 웹 기반의 RESTful API를 사용해 접근할 수 있다.
- 오픈스택 인스턴스는 볼륨, 네트워크, 시큐리티 그룹 정보에 따라 배포된다.
## 챕터 3. 오픈스택 기본 작업 방법
이번 장에서는 작업 사례를 위주로 설명할 것이므로 오픈스택 CLI를 기반으로 예제를 구성할 것이다.
### 3.1 오픈스택 CLI 사용하기
```bash=
# 셸 자동 완성 기능
source /opt/stack/python-novaclient/tools/nova.bash_completion
# demo 테넌트의 demo 사용자로 인증받기 위함
cd ~/devstack
source openrc demo demo
```
### 3.2 오픈스택 API 사용하기
모든 오픈스택의 상호작용은 오픈스택 API 계층으로 돌아온다.
### 3.3 테넌트 모델 운용
테넌트는 호텔의 객실로 비유할 수 있다.
자원의 크기, 이미지, 네트워크 구성 모두를 테넌트별로 구성할 수 있다. 사용자는 테넌트와는 관계가 없지만 특정 테넌트를 위한 역할을 맡을 수 있다.
테넌트는 오픈스택에서 구성과 자원을 구분하고 관리하는 기본적인 방법이다.
#### 3.3.1 테넌트 모델
사용자와 역할 모두 테넌트와 1:N 관계이다.
#### 3.3.2 테넌트, 사용자, 역할 생성하기