|
|||
| $ whoami --team ❯ kt cloud Cloud플랫폼팀 김건희 님 |
1. 문제 정의: "Community 버전의 OpenStack을 내재화한다는"는 것의 무게
클라우드 플랫폼을 구축할 때, 상용 배포판이 아닌 Community 버전의 OpenStack을 코어로 채택하는 순간, 그 의미를 한 번 더 짚어볼 필요가 있습니다.
상용 배포판에서는 벤더(파트너사)가 우리 환경에 맞춰 OpenStack을 딜리버리하고, 패치와 책임까지 함께 가져갑니다.
반면 Community 버전을 직접 쓰기로 했다면? 그 역할을 대신 수행해줄 파트너가 사라집니다.
즉, 코드 관리 → 빌드 → 패치 → 검증 → 배포에 이르는 전체 워크플로(Workflow)를 우리가 직접 구성하고, 소유하고, 지속적으로 운영해야 합니다. 저희는 이를 단순한 운영 부담이 아니라 "OpenStack 내재화의 기반" 으로 보았고, 그 핵심은 다음 한 문장으로 정리됩니다.
단순히 Community 버전의 OpenStack을 설치하고 끝내는 것이 아니라, OpenStack이라는 거대하고 끊임없이 변화하는 소프트웨어의 Supply Chain을, 우리 클라우드 환경에 맞춰 직접 구축하고 운영하는 일을 해내야 한다.
Upstream과 Downstream이 공존해야 한다
플랫폼이 성장하면서 처음엔 Community 구성을 그대로 쓰다가, 점차 이미지 자체 빌드, Helm Chart 수정·패키징, 드라이버 버그 패치, 신규 기능 개발 같은 "우리만의 변경"이 코드·이미지·차트 전반에 누적됩니다.
그 결과 환경에는 Upstream(Community)과 Downstream(자체) 요소가 혼재합니다. kt cloud는 이를 정리하기 위해 Community OpenStack을 Upstream으로 삼고, kt cloud PLATFORM 설계에 맞춰 동작하는 자체 Downstream을 KTC OpenStack으로 내재화하고 있습니다. Code → Image → Chart 전 체인을 kt cloud 아키텍처에 맞춰 직접 구동하는 — 일회성 배포가 아니라 지속적으로 돌아가는 워크플로·파이프라인·공급망(Supply Chain) 그 자체를 만드는 일입니다.

Downstream인 “KTC OpenStack” 개발 원칙
자체 기능구현과 패치 등이 늘어날수록 Upstream의 새 릴리스를 따라가기 어려워지므로, "어디까지 손대고 어디서부터 손대지 않을지"에 대한 기준이 필요합니다. 그래서 저희는 다음 세 가지 원칙을 세웠습니다.
1. Upstream(Community OpenStack)을 그대로 사용하는 것을 기본으로 한다.
2. 단, Upstream에 없으면서 꼭 필요한 기능이거나 주요 버그 수정인 경우에 한정해서 Downstream에서 자체 구현한다.
3. 자체 구현한 내용은 가능한 한 Upstream에 지속적으로 Contribution한다.
결국 Downstream인 KTC OpenStack은 Upstream의 정기 릴리스(예: 2025.1 → 2026.1 …)를 계속 반영하면서 자체 패치·기능도 함께 유지해야 합니다.
그러면 여기서 발생하는 모든 "변화"를 어떻게 검증할 것인가가 가장 중요한 질문이 됩니다.
2. KTC Gating System은 왜 필요한가?
"변화에 대한 검증"이라는 요구는 결국 CI 파이프라인의 문제로 귀결됩니다.
파이프라인과 Job 기반의 테스트라면 GitHub Actions, Jenkins 등 대중적인 선택지도 많습니다. 그럼에도 저희는 이 검증 체계 — KTC Gating System — 를 Zuul.CI 기반으로 구축했습니다. 그 이유를 풀어보겠습니다.
"Gating System"과 "Zuul.CI"
먼저 용어를 정리하면, Gating System은 변경 사항이 메인 브랜치에 병합되기 전에 정의된 파이프라인과 Job으로 검증을 통과(gate)시키는 체계입니다. 그리고 Zuul.CI는 OpenStack을 포함한 OpenInfra 재단이 실제로 이 Gating System으로 사용 중인 오픈소스 소프트웨어입니다. (Netflix의 게이트웨이 프레임워크 'Zuul'과는 다른 프로젝트입니다.)
- 공식 문서: Zuul - A Project Gating System
- 실제 동작 현황: OpenStack의 Zuul.CI Status — (지금 이 순간에도 돌아가는 파이프라인을 볼 수 있습니다.)
실제로 Upstream OpenStack에서는 개발자가 코드 리뷰 시스템(Gerrit)에 코드를 올리면, Zuul.CI가 미리 정의된 파이프라인을 따라 Job을 실행하여 변경 사항을 검증합니다.
| Upstream(opendev.org) Gerrit | Upstream(opendev.org) Zuul.CI |
![]() |
![]() |
KTC Gating System도 Zuul.CI를 선택한 이유
"Upstream을 기본으로 사용한다"는 원칙은 검증 관점에서 강한 제약이 됩니다.
Downstream인 KTC OpenStack은 Upstream의 검증 파이프라인과 Job을 "당연히" 통과해야 한다.
Downstream 코드에서 Upstream의 기존 Job이 실패한다면, 이는 기능 "추가"가 아니라 기존 기능의 회귀(Regression) 신호이자 내재화 방향성에 어긋난다는 뜻입니다. 따라서 자체 패치·피처가 반영되더라도 변화하는 Upstream의 Job을 모두 통과해야 한다는 것이 핵심 기준입니다.
그렇다면 이 방대한 Upstream Job들을 Downstream인 KTC OpenStack에서도 동일하게 쓰려면 어떻게 할까요? 일일이 테스트 코드를 전부 복사해 오는 방법이 먼저 떠오르지만, "테스트 코드" 역시 끊임없이 변하기에 단순 복사는 복사하는 순간부터 Upstream과 어긋나 관리의 한계를 만듭니다.
바로 여기에 Zuul.CI를 선택한 결정적 이유가 있습니다. Zuul.CI는 테스트 코드를 복제하지 않고 Git 기반으로 "참조"합니다. Upstream Job이 정의된 Repository를 등록·선언(Import) 하기만 하면 그 Job을 Downstream 검증에 그대로 호출할 수 있고, Upstream에서 정의가 바뀌어도 수동 작업 없이 최신 검증 로직이 따라옵니다. "변화하는 Upstream 검증 자산을 그대로 따라가야 한다"는 우리 문제에는 Upstream인 OpenStack과 동일한 Flow가 가장 잘 맞았습니다.
KTC Gating System의 두 축과 아키텍처
위와 같은 이유로 우리는 KTC OpenStack 검증을 위해 Upstream과 동일하게 Zuul.CI 기반으로 KTC Gating System을 구축하였습니다. 그리고 KTC Gating System은 크게 두 축으로 구성됩니다.
- Zuul.CI Cluster: 게이팅 로직과 파이프라인을 관리하는 컨트롤 플레인
- Resource Provider: 파이프라인의 Job을 실제로 수행할 인프라 자원 제공자
여기서 Job을 수행할 Resource Provider로 다시 OpenStack을 사용합니다. 즉, Zuul.CI와 OpenStack으로 다시 OpenStack을 검증하는 구조이며, 이 둘은 kt cloud PLATFORM 표준 인프라 구성에 맞춰 Kubernetes 위에서 구동되도록 설계했습니다.

3. Upstream Job "상속"을 통한 KTC OpenStack 검증
이제 KTC Gating System으로 Downstream인 KTC OpenStack을 실제로 어떻게 검증하는지 살펴보겠습니다. 핵심은 Zuul.CI의 Job 상속(Inheritance) 입니다. Zuul.CI에서는 핵심 단위인 "Job"을 프로젝트 간에 공유·상속할 수 있는데, 이를 활용해 다음 전략을 세웠습니다.
Upstream의 테스트 환경 구성, 테스트 코드, 테스트 수행 절차를 모두 그대로 가져다 쓰되, 검증 대상 코드만 Downstream 코드로 교체한다.
KTC OpenStack 검증을 위한 Job 상속 정의 예시
실제 OpenStack의 Neutron을 내재화한 ktc-neutron의 예시를 살펴보겠습니다. 두 가지 작업으로 진행됩니다. 먼저 상속 기반의 Job을 선언하고, 선언한 Job을 ktc-neutron 프로젝트의 파이프라인에 추가합니다.
ktc-neutron 전용 Job
# "ktc job" 선언
- job:
name: ktc-neutron-tempest-plugin-ovn-2025-1 # ktc Job 정의
parent: neutron-tempest-plugin-ovn-2025-1 # upstream Job 상속
required-projects:
- name: openstack/devstack
override-checkout: stable/2025.1
- name: openstack/requirements
override-checkout: stable/2025.1
- name: kt-cloud-stack/ktc-neutron # 검증 대상만 ktc 코드로 교체
vars:
devstack_plugins:
neutron: https://github.com/kt-cloud-stack/ktc-neutron.git # ktc 코드로 교체
- parent로 Upstream OpenStack이 제공하는 Neutron Job을 그대로 상속합니다.
- required-projects와 변수에서 검증 대상 프로젝트만 Downstream인 ktc-neutron 코드로 교체합니다.
ktc-neutron 파이프라인에 위에서 정의한 Job 추가
# Pipeline 에 "ktc job" 추가
check:
jobs:
- ktc-neutron-tempest-plugin-ovn-2025-1 # 파이프라인에 ktc job 추가
- ktc-neutron의 변화를 검증하는 파이프라인에 위 Job을 추가합니다.
이를 통해 실제 수행되는 내용은 아래와 같습니다.
| Job | ktc-neutron-tempest-plugin-ovn-2025-1 |
| 필요 사양 | VM 1대 (8C8G) |
| 수행 내용 |
|
예시로 본 Job "상속"의 의미
위 예시에서 우리가 작성한 것은 수백 줄의 테스트 로직이 아니라, "어떤 Upstream Job을 상속하고 어떤 코드로 동작시킬지"를 선언하는 몇 줄뿐입니다.
즉, 테스트 환경 구성과 검증 절차는 Upstream Job에 그대로 "위임"하고, 우리는 그 위에서 검증 대상만 KTC OpenStack 코드로 바꿔 끼울 뿐입니다.
그리고 KTC Gating System을 통한 Job 수행
이제 위에서 선언한 Job과 파이프라인 구성에 따라, KTC Gating System에서 다음과 같이 동작합니다.

4. 마무리: 무엇을 얻었고, 어디로 가는가
![[구축사례] kt cloud PLATFORM OpenStack 검증용 Zuul.CI Gating System 구축](https://blog.kakaocdn.net/dna/bqKxBh/dJMcadJrBB3/AAAAAAAAAAAAAAAAAAAAAFWcj4tFCHDPZeSw5VB4sHxj63RQJMgoCPwVdni0KZ1Q/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1785509999&allow_ip=&allow_referer=&signature=IzwawmOp1nEZ0yn7Vm83ICQ9APo%3D)
이번 작업에서 저희가 얻은 가장 큰 교훈은 단순합니다. 검증 자산은 "복사"하지 말고 "참조"하라는 것입니다.
복제해 둔 테스트 코드는 당장은 편하지만 Upstream이 바뀔 때마다 뒤처져 결국 부채가 됩니다. 반대로 Git으로 참조하고 Job을 상속하면, Upstream의 변화가 자연스럽게 우리 검증으로 흘러들어와 애쓰지 않아도 최신 기준이 유지됩니다. 여기에 "Upstream Job은 반드시 통과한다" 는 규칙 하나만 더하면, 우리 코드가 기존 기능을 망가뜨리는 순간(회귀, Regression)을 가장 빠르게 잡아낼 수 있습니다.
이와 함께 KTC Gating System은 아직 시작 단계입니다. 앞으로 적용 범위는 OpenStack 코드 검증을 넘어 실제 VM에 kt cloud PLATFORM 아키텍처대로 클러스터까지 자동 구성해 검증하는 데까지, 검증 범위는 Upstream Job을 넘어 kt cloud PLATFORM 목표에 맞춘 자체 Job 설계까지 넓혀갈 계획입니다.
거대한 OpenStack과 같은 오픈소스를 직접 운영한다면, "변화를 어떻게 검증할 것인가"는 피할 수 없는 질문입니다. 이 글이 같은 고민을 하는 분들께 작은 참고가 되길 바랍니다.
?› 자주 묻는 질문 FAQ
'Tech Story > Cloud Architecture' 카테고리의 다른 글
| [기술사례] Ceph 기반 스토리지 내재화로 상용 스토리지 대체하기 (0) | 2026.07.13 |
|---|---|
| [백업·DR] kt cloud 재해복구 설계: Multi-AZ와 Multi-Region (0) | 2026.05.20 |
| [기술리포트] 클라우드 네이티브 4편 : 상태 관리와 데이터 일관성 - 안정성·신뢰성 확보 전략 (0) | 2026.02.27 |
| [기술리포트] 클라우드 네이티브 3편 : 장애 도메인과 격리 설계 - 가용성·복원력 강화 전략 (0) | 2026.02.13 |
| [기술리포트] 클라우드 네이티브 2편 : 애플리케이션 이식성 강화 - 컨테이너·배포 전략 (0) | 2026.02.05 |

