오픈소스 2024 컨트리뷰션에 참여하게되어 오픈스택 기여를 앞두고, 제대로 정리가 안되어 이해하기 쉽지 않아 이에 대한 개념을 정리해보고자 합니다.
( 듣고나면 까먹는 금붕어이기 때문..)
모든 개념은 멘토링 별도 자료를 참고했습니다.
오픈스택이란?
IaaS 형태의 프라이빗/퍼블릭 클라우드 구축을 위한 오픈소스 플랫폼다.
과거의 오픈스택은 테넌트별로 가상머신을 관리하는게 목적이었지만,오늘날의 오픈스택은 베어메탈도 만들 수 있고, 메그넘이라는
컴포넌트를 이용해서 컨테이너 서비스도 만들 수 있는 단계까지 올라왔다.
클라우드 인프라의 기반이 되어가고 있다.
오픈스택은 프라이빗 클라우드를 구축하고자 하는 기업들이 많이 사용을 한다.
퍼블릭 클라우드는, CSP 에 종속(의존) 성이 강하며 비용이 높다는 측면이 있기 때문에 이러한 점에서 오픈스택을 많이 활용하고 있다고 한다.
OPENSTACK LANDSCAPE
오픈스택에는 다양한 컴포넌트들이 있습니다.
Core Component
- Nova: 가상의 서버를 생성 및 관리
- Glance: 서버의 이미지 생성 및 관리
- Cinder: 블록 스토리지를 생성 및 관리
- Neutron: 가상의 네트워크 생성 및 관리
- Keystone: 사용자에 대한 인증
- Swift: 오브젝트 스토리지를 구성
- Horizon: Horizon 대시보드를 통해 GUI 환경에서 오픈스택의 구성요소들을 컨트롤 가능
DNS Component
openstack 동작 방식
오픈스택은 기본적으로 Api 서비스와 Agent 서비스가 각각 있다.
ex ) Nova
1. 동일 컴포넌트내의 통신 ( nova api <- -> nova agent)
- Rabbit MQ 라는 서비스를 이용하게되는데, 동일 컴포넌트 내에서는 RPC 통신을 하게된다.
- nova API 가 사용자로부터 rest api 요청을 받으면, 그 정보를 토대로, Nova Compute는 맞는 RPC Call 이 들어오면 그에 맞는 동작을 하게된다.
- Nova Compute 는 인스턴스를 만들어주는 역할을 하기 때문에, libvirt 를 호출하고, kvm 을 이용해서 인스턴스를 만든다.
- 오픈스택은 직접 가상화를 하고, 생성하는 것이 아닌 플러그인과 드라이버를 이용한 관리를 하는 것이다.
2. 다른 컴포넌트 내의 통신 ( nova api -> 다른 컴포넌트의 api 호출)
각각의 api 서비스들은 다른 agent 와 통신할 때에는 동일한 컴포넌트간 통신이기 때문에 RPC 통신이라 불리는 Rabbit MQ 를 이용한 통신을 하는 것이다.
인스턴스 생성 Flow
api 로 생성 요청을 접수하는 처리와 요청에 따라서 실제로 가상 서버를 생성하는 처리가 비동기적으로 분리되어 실행된다.
1. 사용자가 인스턴스 생성 요청을 엔드포인트 url 을 호출하게되면
2. 오픈스택은 요청을 접수받아서 실제 가상서버의 정보를 설정한다.
3. 해당 정보를 받은 후, 각종 컴포넌트들에 요청을 날린다.
4. 사용자에게 인스턴스 정보를 전달한 뒤에
5. hypervisor 에게 인스턴스 생성을 요청한다
API 의 비동기 처리 방식
인스턴스 생성하는 api 를 실행시켜도 즉시 실행되는 것이 아니다.
openstack server show 명령어로 상태를 확인해보면, BUILD 인 것을 확인할 수 있다.(열심히 libvert 가 kvm 과 함께 만드는중)
완료될 때까지 GET 을 활용해서 상태 확인을 반복적으로 check 한다.
인스턴스가 생성되기 까지의 처리 흐름
오픈스택에 인스턴스 정보와 생성 요청을 보내면, nova api 와 rabbit MQ 의 RPC 통신을 통해 메시지 큐에 정보를 저장하게된다.
어떤 flavor 를 쓰는지에 따라 어떤 hypervisor 로 인스턴스를 생성시킬지 스케줄링 해주는 것 -> 컨덕터
정보를 받아서 상태관리 DB 에 보내서 어떤 하이퍼바이저를 할당할 지 스케줄링 해준다.
스케줄러가 상태관리DB 를 확인해서 다시 메시지 큐에 인스턴스 생성 요청을 보낸다.
nova compute는 메시지 큐에서 본인에게 온 RPC Call 을 받아 hypervisor 를 확인해서 인스턴스를 kvm 을 이용해 생성을 한다.
python-openstackcli 프로젝트란?
- OpenStack 클라우드 서비스에 대한 명령 줄 인터페이스 (CLI) 도구이고, 사용자는 OpenStack 환경에서 다양한 서비스를 관리하고 조작할 수 있다.
- 이 프로젝트는 다양한 OpenStack 서비스 (예: Compute, Identity, Image, Network 등)에 대한 일관된 CLI를 제공하여 사용자가 손쉽게 OpenStack 리소스를 관리할 수 있도록 도와준다.
python-openstackclient의 주요 기능
- 통합된 CLI: 각 OpenStack 서비스에 대한 개별 CLI 도구 대신 하나의 통합된 CLI를 제공하여 사용자의 편의성을 제공
- 확장 가능: 플러그인 아키텍처를 통해 새로운 서비스나 기능을 쉽게 추가 가능
- 자동 인증 및 세션 관리: 사용자가 설정한 인증 정보와 세션을 바탕으로 OpenStack API와 상호 작용
# git 주소
https://opendev.org/openstack/python-openstackclient
탄생 배경
원래는 각 컴포넌트 마다 CLI(client)가 따로 존재한다.
- openstackcli : openstack image list
- glance cli : glance image-list
- 하지만 컴포넌트별로 따로 개발이 되다보니 option이나 코드 구조가 일관성이 없어진다.
- 예를 들어, 테넌트 ID를 nova에선 tenantd-id, glance에선 tenantd_id등 (예시일뿐 실제 X)
- 컴포넌트별로 코드 구조나 개발방식이 달라 다른 컴포넌트에 기여하기가 어렵다.
setup.cfg
- setup.cfg 파일은 Python 프로젝트의 메타데이터와 구성 옵션을 정의하는 파일이다.
- 이 파일은 주로 Python 패키징 도구인 setuptools와 함께 사용되며, 프로젝트의 설정 정보를 명시적으로 지정할 수 있는 구성 파일이다.
- 설정 값
- 메타데이터: 프로젝트 이름, 버전, 저자, 라이센스 등의 기본 정보.
- 옵션: 설치 옵션, 종속성, 테스트 요구 사항 등의 설정.
- 엔트리 포인트: CLI 명령어와 그에 매핑되는 함수 지정.
- 패키징 정보: 포함될 패키지와 데이터 파일 등의 정보.
역할
- 프로젝트 구성 및 관리: 프로젝트의 종속성, 메타데이터, 엔트리 포인트 등을 중앙에서 관리.
- 자동화: 빌드 및 배포 프로세스를 자동화.
- 일관성: 여러 개발자 간의 환경 일관성 유지.
- setup.cfg 파일을 통해 프로젝트의 다양한 설정을 한 곳에서 관리함으로써, 패키징과 배포 과정이 더 체계적이고 간편해진다.
코드
- get_parser : 함수명 그대로 입력한 명령어의 argv를 파싱하는 함수이다.
- take_action : 실제 API 호출이나 값을 받아와 파싱하여 사용자에게 값을 전달 해주는 핵심 함수
우리는 take_action 을 더 많이 건드릴 것 같음
openstack server list 분석해보기
openstack server list —debug
인증 및 openstackcli를 사용하기 위한 정보 설정
keyston : identity 엔드포인트를 가지고 있음 ( 사용자 인증 )
사용할 컴포넌트 API 버전에 맞는 client 를 셋팅하는 부분
저 커맨드에 맞는 함수를 호출한다가 보이는 부분
컴포넌트간 인증을 위해 사용할 token 발급한다. nova 가 인증과 인가가 되었을 경우에만 보내기 때문에
키스톤으로 특정 api 요청을 보내고, 통신이 정상적으로 되는지 확인한다.
이때 토큰은 헤더에 있다.
openstack cli 가 api 요청을 보내기 위한 endpoint 를 아는 방법은?
키스톤에 토큰 요청을 하게되면, body 에 포함된 catalog 부분안에 내가 사용하고있는 컴포넌트에 대한 모든 endpoint 를 반환하게 되기 때문에, 이 endpoint 를 확인해서 요청을 보낸다.
compute : nova api 엔드포인트
image : glance 엔드포인트
여튼 이렇게 여러 컴포넌트의 엔드포인트를 통해 api 를 호출한다.
openstack api 명세
어떤 엔드포인트가 있는지 확인 가능
- nova api : https://docs.openstack.org/api-ref/compute/
- keystone api
- glance api
api 버전에 따라 return 값의 정도(양,디테일)가 다르다.
Openstack SDK
OpenStack SDK는 OpenStack의 기능들을 손쉽게 이용하여 새로운 애플리케이션을 만들 수 있게 만들어주는 도구다.
대표적으로 OpenStack Client 프로젝트에서 OpenStack의 정보를 받아오는 과정에서 OpenStack SDK를 많이 사용하고 있다.
OpenStack SDK 구조
OpenStack SDK는 아래의 구조로 이루어져 있다. (아래 예시는 compute sdk를 나타낸다)
openstack/
connection.py
resource.py
compute/
compute_service.py
v2/
server.py
_proxy.py
tests/
compute/
v2/
test_server.py
또한 이 구조는 크게 Resource, Proxy, Connection 세 개로 나눌 수 있다.
Resource
Resource는 일반적인 REST API의 CRUD를 호출하는 데에 사용된다.
openstack/resource.py 에 선언되어 있는데, 해당 파일에서는 REST API의 CRUD를 호출하거나, 응답 받기 위한 위한 정보들(Header, Body, URI, QueryParameter 등)을 선언하고 있다.
해당 파일의 함수들을 이용하여 openstack/compute/v2/server.py 에서 compute 프로젝트에서 사용하게 되는 API의 CRUD 호출을 직접적으로 담당한다.
server.py 에서는 api 요청을 하기 위한 정보들을 resorce.py 를 이용해서 저장한다는 소리이다.
Proxy
각 서비스는 openstack/<program_name>/vX/_proxy.py 모듈 내에서 Proxy에 기반한 Proxy 클래스를 구현한다.
예를 들어, v2 compute 서비스는, Proxy가 openstack/compute/v2/_proxy.py에 존재한다.
Proxy 클래스는 Resource 클래스의 기능들을 이용하여 좀 더 편리한 기능들을 갖고 있다.
def list_flavor(self, **params):
return flavor.Flavor.list(self.session, ** params)
위 코드는 openstack.compute.v2.flavor.Flavor.list 메소드를 동작시다. 이 동작은 Resource 클래스의 list 메소드를 실행합니다.
Connection
Connection 클래스는 구현된 proxy 객체를 통해 resource 객체를 호출하는 역할을 합니다. 또한, configuration을 이용하여 오픈스택과 사용자를 연결하는 역할을 맡고 있다.
해당 클래스의 위치는 openstack/connection 이다.
어렵다 어렵다아아
Designate
DNS에 대해서 기본적인 개념은 파악하였으니 OpenStack의 Designate 컴포넌트에 대해 알아보겠다.
Designate는 OpenStack에서 DNS-as-a-service를 담당하는 컴포넌트로 DNS 서버의 역할을 맡고 있다.
REST API를 이용하여 DNS 레코드, Zone, 이름을 관리합니다. Neutron과 Nova 컴포넌트와 통합하여 사용할 수 있게 구성도 가능하다. 이 때는 floating ip나 인스턴스가 생성될 때 레코드가 자동으로 생성된다.
DNS의 백엔드 플러그인으로 사용하는 것들은 BIND9, PowerDNS 등이 있다.
Designate는 API, Producer, Central, Worker, Mini DNS 등의 서비스로 구성되어 있다.
- API - Designate의 RESTAPI 처리를 담당한다.
- Central - 레코드 데이터/존의 용량/검증을 담당하고, Worker에게 CRUD 요청을 전송한다.
- Mini DNS - Designate 데이터베이스에만 있는 존 전송 요청을 처리한다.
- Worker - Designate의 네임서버에서 필요한 작업들을 수행한다.
- Producer - API 작업 외에 있는 작업들을 수행하고, 정기적인 작업들(예: 정기적 복구)을 수행한다.
Designate의 동작을 Neutron과 함께 되도록 구성하여 동작하는 예시이다.
사용자가 Designate에 zone1.cloud.openstack.org 와 zone2.cloud.openstack.org 라는 두 개의 영역을 만들었습니다 . 그러면 SOA 레코드가 있는 Designate 네임서버에 두 개의 새로운 zone이 생성된다.
그런 다음 사용자는 Neutron에 두 개의 네트워크를 생성합니다. 하나는 zone1.cloud.openstack.org 가 할당된 프라이빗 네트워크이고, 다른 하나는 zone2.cloud.openstack.org 가 할당된 퍼블릭 네트워크이다 .
그런 다음 Nova에서 vm1을 만들고 Neutron의 개인 네트워크에 연결하고 floating IP에 vm2를 퍼블릭 네트워크에 직접 연결했다. 이러한 각 작업은 Neutron이 사용자를 대신하여 Designate에 레코드 생성을 요청하는 일련의 이벤트를 트리거하고, 최종 결과는 네임서버에서 레코드가 생성되어 역방향 조회를 허용하기 위해 PTR 레코드와 함께 vm 이름을 도메인에 매핑한다.
아직도.. 명확한 이해는 되지 않지만, 다음 글에서는 내가 기여해야 할 부분의 코드를 이해하고, 이에 대해서 적어보겠다.
'☁️2024 > Openstack' 카테고리의 다른 글
Openstack 기여하기 #4 (0) | 2024.10.04 |
---|---|
swift - 오브젝트 스토리지 동작 원리 (4) | 2024.09.26 |
Openstack 기여하기 #3 (0) | 2024.09.12 |
Openstack 기여 하기 #2 (2) | 2024.09.02 |
Openstack 기여 하기 #1 (0) | 2024.08.26 |