레거시 인프라 작살내고 하이브리드 클라우드 만든 썰
안녕하세요, 토스페이먼츠 Infra Team Leader 정상현, DevOps Engineer 박명순입니다.
2020년 8월, 결제 산업 혁신을 목표로 출범한 토스페이먼츠. 하지만 처음부터 새롭게 시작한 것이 아니라, 20년 넘게 운영되던 PG 사업을 인수하며 시작했습니다. 그리고 그 인프라에는 상상을 초월하는 레거시가 기다리고 있었죠.
이번 글에서는 오픈소스 기반 OpenStack 프라이빗 클라우드를 직접 구축해 퍼블릭(AWS)과 Active-Active 하이브리드 클라우드(다중 Pod/클러스터)로 운영하며 자동화·모니터링·고가용성을 확보해 “어느 클라우드인지 몰라도 배포 가능한” 환경을 만들었습니다.
1997이라는 숫자의 비밀
조금 뜬금없지만 여기 1997이라는 숫자가 있습니다. 이 숫자가 어떤 의미인지 혹시 짐작이 가실까요? 힌트는 서버와 관련되어 있지만, 서버에서 흔하게 볼 수 있는 숫자는 아닙니다.
라우팅은 네트워크 장비가 하는 것 아니었나요?
이 숫자를 설명하려면 네트워크 라우팅에 대한 얘기를 해야 합니다. 일반적으로 서버 1, 2, 3이 동일한 네트워크 장비에 연결되어 있고, 원격지 네트워크에 각각 서버-A와 서버-B가 있는 상황을 생각해 보겠습니다.

서버 1, 2, 3이 서버-A 또는 서버-B로 가려고 하면 어떻게 경로를 찾아갈까요? 당연하게도 이 정보는 서버들이 연결된 네트워크 장비에서 가지고 있습니다. 서버 입장에서는 고민 없이 특정 목적지로 향하는 패킷을 네트워크 장비로 보내고, 네트워크 장비에서 패킷의 목적지를 확인한 후 해당되는 경로로 전달하게 됩니다.
그런데 우리가 인수한 인프라는 달랐습니다
특별할 것 없어 보이는 이 이야기를 드리는 이유는 저희가 맞닥뜨렸던 현실이 이렇지 않았기 때문입니다.
저희가 인수한 인프라는 라우팅을 네트워크 장비에서 하지 않았습니다. 모든 목적지에 대한 경로 정보는 서버에 라우팅 형태로 들어가 있고, 서버는 패킷을 보낼 때 자신의 라우팅 테이블을 보고 다음 목적지를 확인하게 되어 있었습니다.

네트워크 장비는 경로 결정에 관여하지 않고, 단순히 전송을 위한 통로 역할만 하고 있었어요. 이는 새로운 경로가 추가될 때마다 관련된 모든 서버에 반영이 필요함을 의미했고, 관리해야 할 포인트는 너무나 많을 수밖에 없었습니다.
1997의 정체
그리고 이런 구성이 오랜 기간 동안 유지되다 보니 다음과 같은 상황이 발생했습니다.

네, 1997은 여기서 나왔습니다. 라우팅이 거의 2,000개가 있는 서버들이 있었어요.
네트워크 장비에 2,000개가 있어도 결코 작은 숫자라고 할 수는 없을텐데, 이런 서버들을 이대로 계속 일일이 관리하는 것은 어떻게 생각해 봐도 효율적인 일이라고 결론 내리기는 어려웠습니다.
레거시 인프라의 참상
서버 라우팅 문제는 전체 인프라 구성 이슈의 일부일 뿐, 실제로는 훨씬 더 많은 문제가 있었습니다.
이런 상황에서 이 인프라에 새로운 서비스를 올리는 것은 저희로서는 하기 어려운 선택이었죠.
첫 번째 해결책: 퍼블릭 클라우드
그래서 토스페이먼츠가 한 선택은 퍼블릭 클라우드를 사용하는 것이었습니다.
기존 레거시 인프라는 레거시 서비스를 유지하면서 신규로 만들어지는 제품들은 클라우드에 포팅하는 형태로 서비스를 제공했습니다. 이는 빠르게 인프라 준비가 가능한 클라우드의 장점을 충분히 활용하는 전략이었고 잘 동작해서, 새로운 제품들을 현대화된 인프라에서 서빙할 수 있었습니다.
하지만 퍼블릭 클라우드에도 한계가 있었습니다
서비스가 점점 커질수록 퍼블릭 클라우드에 들어가는 비용도 증가할 수밖에 없었고, 특히 환율 변화에 따라 비용이 크게 영향을 받았으며, 퍼블릭 클라우드와 온프레미스의 레거시 인프라 간 DR 구성은 아키텍처의 차이 때문에 쉽지 않은 일이었습니다.
그 외에도 전용회선 등 퍼블릭 클라우드에서 제공해 주지 않는 인프라 구성 요소들 때문에 온프레미스 환경은 여전히 필요했고, 깊이 있는 인프라 트러블슈팅이나 세부적인 튜닝 등은 저희가 컨트롤할 수 없는 부분이기 때문에 가시성이 부족한 아쉬움 또한 존재하는 것이 사실이었습니다.
우리의 결론: 프라이빗 클라우드 + 퍼블릭 클라우드
그래서 저희가 내린 결론은 IDC 내의 낡은 레거시 인프라는 버리고 프라이빗 클라우드를 새로 만드는 것이었습니다.
프라이빗 클라우드는 AWS나 Azure 같은 클라우드 서비스를 저희가 소유한 데이터 센터에 직접 구축하는 것을 의미하는데요. 가장 큰 장점은 클라우드 서비스의 모든 구성 요소들에 대한 통제권을 저희가 거의 100% 가져갈 수 있다는 것이었어요.
퍼블릭 클라우드가 편리하기는 하지만 인프라 측면에서 컨트롤할 수 있는 범위가 매우 제한적인 것이 사실인지라 이는 저희에게 매우 중요한 요소였습니다.
하지만 모든 것을 우리가 제어할 수 있다는 이야기는 모든 것을 우리가 해야 한다는 것과 동일한 의미가 되기도 합니다. 즉, 어떻게 프라이빗 클라우드를 구축/운영하느냐에 따라서 이는 장점이 될 수도 단점이 될 수도 있었습니다.
최종 목표: 하이브리드 클라우드
그리고 이렇게 만든 프라이빗 클라우드를 퍼블릭 클라우드와 함께 Active-Active로 운영하는 하이브리드 클라우드를 만드는 것이 최종 목표였습니다.
이 둘을 합쳐서 저희가 필요한 자원들을 효율적으로 배치하여 사용할 수 있는 환경을 준비하는 것이 궁극적인 목표였습니다. 이미 퍼블릭 클라우드는 사용하고 있었기 때문에, 결국 관건은 프라이빗 클라우드를 어떻게 구성하느냐가 핵심이었어요.
프라이빗 클라우드가 만족해야 할 3가지
이런 배경에서 어떤 프라이빗 클라우드를 만들어야 하는지 고민해본 결과 크게 3가지를 만족시켜야 한다는 결론에 도달했습니다.
1. 애자일한 인프라
클라우드를 사용하는 가장 큰 목적 중 하나는 제품의 개발 속도를 빠르게 뒷받침 할 수 있는 인프라 환경을 만드는 것이라고 생각했기에 이 부분은 어찌 보면 가장 기본적으로 채워져야 하는 내용이었습니다.
2. 유연성
저희가 인프라 관점에서 희망했던 유연성은 인프라의 고객들이 어떤 요구 사항을 내놓더라도 만족시킬 수 있는 환경을 준비하는 것이었습니다.
VM, 컨테이너, K8S 같은 다양한 인스턴스 타입부터 로드밸런서, 공유 스토리지 등의 자원들까지 모든 제품 요구 사항에 대응 가능한 인프라를 준비하는 것이 또 다른 큰 목표였습니다.
3. 오픈소스 기반
그리고 마지막으로 이 모든 것을 상용 솔루션보다는 오픈소스 기반의 환경으로 준비하고 싶었습니다.
상용 솔루션의 높은 비용이 꺼려진 이유도 있었지만 그보다는 기술을 완전히 내재화해서 우리 것으로 만들고 싶은 욕심도 있어서였죠.
OpenStack을 선택하다
결론적으로 저희가 선택한 프라이빗 클라우드 플랫폼은 OpenStack이었습니다.

OpenStack은 필드에서 가장 널리 쓰이는 클라우드 플랫폼으로, 퍼블릭 클라우드에서 많이 사용하는 구성 요소들을 모두 OpenStack에서도 동일하게 사용할 수 있습니다. 많이 사용되고 대규모 환경에서 충분히 검증되었다는 점에서 OpenStack을 선택한 것은 어떻게 보면 쉬운 결정이었어요.
그런데 문제는 다른 데에 있었습니다
이 OpenStack을 구축해야 할 시스템 엔지니어가 당시 저희 팀에는 단 두 명뿐이었습니다.
그리고, 이 두 명은 OpenStack을 운영해본 경험이 전무했습니다.
안 그래도 업계에서는 OpenStack의 가장 큰 단점으로 운영 난이도가 높다는 점이 꼽히고 있었는데, 이 인력으로 커뮤니티 버전의 OpenStack을 단순히 구축하는 것을 넘어 프로덕션 목적의 시스템의 기반 인프라로 운영한다는 것은 단순히 욕심만으로 될 일은 아니었죠.
실제로 시스템 엔지니어 두 명으로 OpenStack을 준비한다고 했을 때:
- 점잖으신 분들은 저에게 "용감하다"고 했고
- 조금 더 직설적인 분들은 "미쳤다"고 했습니다
준비하면서 어려움을 수도 없이 겪었지만 포기하지 않고 끝까지 올 수 있었던 건 팀의 헌신적인 노력과 열정 때문이었습니다.
첫 번째 고민: 2명으로 프로덕션 레벨 운영이 가능한가?
가장 근본적인 질문이자 첫 번째 고민이었습니다. 이 질문에 대한 대답을 하기 위해서는 직접 경험을 해보는 것이 필요하다는 데에는 쉽게 의견이 모아졌습니다.
1. 경험 축적
총 3가지의 버전의 OpenStack을 각각 수십 번씩 설치해보고 장애 시나리오를 재현해가면서 경험치를 늘려나갔고, 이를 통해 OpenStack의 아키텍처에 대한 이해도를 높일 수 있도록 했습니다.
2. 튜닝
어느정도 이해도가 올라온 이후에는 튜닝이 필요했습니다. 유저 환경이 모두 다르다 보니 커뮤니티 버전을 그대로 사용해서는 저희의 니즈를 모두 만족시킬 수가 없었습니다.
예를 들어서 OpenStack의 로드밸런서인 옥타비아(Octavia)에서 기본적으로 남겨주는 로그는 저희가 원하는 포맷이 아니었기에 소스를 수정해서 필요한 로그들을 남길 수 있도록 했습니다. 이는 오픈소스의 장점을 활용하는 것이기도 했지만, 저희가 그만큼 이해도를 끌어올렸다는 의미이기도 했어요.
3. 자동화
적은 인력으로 대규모의 시스템을 운영하기 위해서는 자동화는 필수에 가까웠습니다.
OpenStack 내 VM 인스턴스, 로드밸런서, 사용자 권한 등 모든 자원의 라이프사이클 관리를 앤서블(Ansible)과 테라폼(Terraform) 코드를 이용하여 자동화하도록 하였고, 표준 골든 이미지를 통해 신규 인스턴스 생성까지 10초 이내에 가능하도록 구성하였습니다.
또 이렇게 구성된 정보들은 CMDB에 수집하여 봇을 통해 언제든 쉽게 조회할 수 있게 구현하였습니다.

4. 모니터링
여기까지 구현된 이후의 관건은 장애 상황에 대한 대응이었습니다. 장애 대응의 시작은 감지가 될 텐데요.
Zabbix, Prometheus, Mimir 같은 오픈소스 툴들을 다수 활용하여 저희가 필요하다고 판단한 모든 메트릭들을 수집할 수 있도록 하였고, 수집된 메트릭은 Grafana를 통해 시각화하며, 알람을 빠르게 확인할 수 있는 환경을 구현했습니다.
5. 고가용성 전략
장애 감지 이후의 고민은 어떤 식으로 빠르게 조치할 수 있을 것인가였습니다.
이 부분에서 여러모로 고민한 결과 완전히 독립된 OpenStack 클러스터 2개를 구성하여 평상시에는 Active-Active로 운영하다가 특정 OpenStack 클러스터에 장애가 있을 경우 트래픽 인입을 제거하는 게 가장 빠르게 서비스 가용성을 유지할 수 있는 방법이라는 결론에 도달했습니다.
그래서 서로 간의 의존성을 완전히 배제한 클러스터 2개를 만드는 것을 목적으로 하게 되었고, 결론적으로는 3개의 독립된 클러스터를 구축하게 됩니다.
두 번째 고민: K8S를 어떻게 구성할 것인가?
모던 애플리케이션 인프라 환경은 모두 K8S 기반으로 구축된다고 해도 과언이 아닐 텐데요. K8S의 구성 요소를 잠깐 살펴보면 컨트롤 플레인과 데이터 플레인으로 나누어집니다.
문제점
퍼블릭 클라우드에서 컨트롤 플레인은 알아서 관리해주는 PaaS 형태의 서비스가 존재하기에 K8S 클러스터 관리에 대한 고민 없이 쉽고 빠르게 사용하는 장점이 있었습니다.
OpenStack에서도 매그넘(Magnum)이라는 유사한 클러스터 관리 서비스가 있지만, 프라이빗 클라우드 구축 목적 중 하나가 저희가 모든 제어권을 확보하는 것이었기에 PaaS 형태보다는 직접 관리가 가능하면서도 쉽고 빠르게 운영이 가능한 방법을 고민했습니다.
해결책: Cluster API
그 해답으로 저희가 선택한 것은 Cluster API입니다.
Cluster API는 K8S 클러스터 자체를 K8S의 리소스로 관리하는 툴킷입니다. 이 방법은 애플리케이션을 K8S로 관리하는 것과 완전히 동일한 장점을 클러스터 관리에 가져다줍니다.

이를 통해 프라이빗 클라우드 환경 위에서도 퍼블릭과 동등한 수준의 편의성을 확보할 수 있었습니다.
세 번째 고민: 네트워크 민첩성
OpenStack이 서비스되기 위해서는 네트워크 장비들이 있어야 하고, 저희들은 여러 가지 이유로 이 장비들에 많은 역할들을 부여했는데요. 전통적인 네트워크 운영 방법으로는 클라우드 레벨의 민첩성과 유연성을 확보할 수 없을 것 같다는 고민이 있었습니다.
해결책: NetDevOps
네트워크 운영에도 NetDevOps 형태의 방법론을 적용하기로 했습니다.
Configuration 모듈화
예를 들어 Leaf-A라고 표시된 장비 하나를 예로 들어보겠습니다. 이 장비의 경우 Configuration이 모놀리식 형태가 아니라 각 서비스별로 모듈화된 형태로 저장되어 있습니다.

따라서 신규 서비스가 오픈될 경우 새로운 모듈을 추가하고, 특정 서비스가 종료될 경우 해당 모듈만 제거하는 방식으로 네트워크의 라이프사이클 관리가 가능하게 되어 있습니다.
템플릿화 및 자동 배포
또한 이는 각 장비마다 따로 관리되는 것이 아니라 파이썬 코드로 템플릿화 되어서 네트워크 관리 시스템을 통해서 관리되게 됩니다.
그리고 네트워크 관리 시스템은 이 템플릿을 각 장비에 맞는 파라미터를 적용하여 배포하는 형태로 네트워크 장비에 대한 형상 관리를 수행하게 됩니다. 마치 애플리케이션 배포 파이프라인처럼요.
최종 구성: 3개의 독립된 Pod
이러한 고민과 그에 대한 결과물을 도출하던 끝에 저희는 최종적으로 총 3개의 독립된 OpenStack 클러스터를 구성했습니다. 여기서 말하는 Pod는 K8S에서 이야기하는 pod와는 다른 개념으로 서버, 네트워크, 스토리지 등이 모인 인프라 관점에서 하나의 완결된 서비스 단위로 이해해 주시면 좋을 것 같습니다.

Pod1, Pod2: 프로덕션 서비스용
우선, 프로덕션 서비스를 위한 Pod1, Pod2를 준비했습니다.
두 개는 상호 의존성 없이 완전히 독립되어 있지만 동일한 서비스가 배포되는 공간으로 OpenStack 클러스터 단위의 장애나 메인터넌스에 대비할 목적으로 두 개의 Pod를 구성했습니다. 퍼블릭 클라우드에 익숙하신 분들이라면 AZ(가용 영역)를 생각해 주시면 좋을 듯합니다.
Pod0: 관리 목적 클러스터
그리고 Pod0라는 이름으로 관리 목적의 클러스터를 한 개 더 준비했습니다.
여기에는:
이 위치하는 공간으로 활용하였습니다.
하이브리드 클라우드 완성
그리고 이렇게 준비된 OpenStack 클러스터들을 포함한 전체 하이브리드 클라우드는 다음과 같은 모습이 되었습니다.

4개의 Live 영역
저희가 애플리케이션 관점에서 퍼블릭 클라우드 내 별도 가용 존에 서비스를 각각 Live1, Live2라고 부르고 있었는데요. 그 연장선에서 OpenStack에 구성된 서비스는:
로 불려지게 되었고, 완성된 아키텍처의 주요 특징은 다음과 같습니다.
고가용성 확보
가용성 관점에서:
하여 어떤 단위의 인프라 장애에도 대응 가능한 높은 수준의 가용성을 확보했습니다.
트래픽 플로우
고객은 Live1, 2, 3, 4 어디로 진입해도 동일한 서비스를 제공받게 되며, 센터 간의 트래픽 배분 또 센터 내 트래픽 배분도 저희 필요에 따라 자유롭게 할 수 있도록 구성하여 메인터넌스와 장애 시에 유연하게 대응이 가능하게 되었습니다.
동일 계위 구성
구성 요소 측면에서 특기할 만한 점은, 퍼블릭과 프라이빗 클라우드라는 두 개의 완전히 다른 클라우드지만 동일한 역할의 구성 요소를 동일 계위에 배치해 운영 효율성을 높이고자 했다는 점입니다.

예를 들어:
이렇듯 클라우드는 다르지만 아키텍처는 통일함으로써 개발자가 자신이 애플리케이션을 배포하는 공간이 어느 클라우드인지 알 필요가 없는 환경을 구성했습니다.
애플리케이션 인프라 현대화
이제부터는 하이브리드 클라우드 인프라 위에서 토스페이먼츠 서버플랫폼팀이 어떻게 애플리케이션 인프라를 현대화 했는지에 대해 이야기 해보겠습니다.
하이브리드 클라우드 기본 방향
저희는 하이브리드 클라우드를 구성하면서, AWS 환경에 익숙한 개발자들이 OpenStack 환경의 추가를 마치 AWS 리전이나 계정이 하나 더 생긴 것처럼 자연스럽게 느낄 수 있도록 하는 것을 아키텍처 설계의 기본 방향으로 삼았습니다.
Active-Active 서비스 구조
기존 AWS 인프라는 두 개의 EKS 클러스터를 Active-Active로 구성해 특정 가용 영역의 장애가 전체 서비스 장애로 이어지지 않도록 했으며, 클러스터 업그레이드 등의 작업도 원활하게 수행할 수 있었습니다.
저희는 OpenStack 인프라 구성을 AWS와 최대한 유사하게 만들고, AWS와 OpenStack을 클라우드 레벨에서도 Active-Active로 운영하는 서비스 구조를 만들기로 했는데요. Active-Active 운영은 구성과 운영 모두 Active-Standby보다 훨씬 어렵지만, Standby에서 Active가 될 때의 오동작을 최소화할 수 있다는 장점 때문이었습니다.

클라우드 리소스 매핑
저희는 OpenStack 구성을 AWS와 최대한 유사하게 형상 관리하기 위해, AWS 리소스 별로 OpenStack 환경에 대응되는 리소스를 매핑을 진행했습니다. EC2와 NLB는 OpenStack의 Nova와 Octavia로, ECR은 오픈소스 Harbor로, ALB는 F5사의 BigIP로 구성 했습니다. 가장 핵심 리소스인 EKS는 인프라팀에서 Kubernetes Cluster API를 이용해 구성했으며, 이 문서에서는 OpenStack Kubernetes Service의 약어로 OKS라고 표현하겠습니다.

배포 시스템 확장
AWS와 OpenStack을 Active-Active로 운영하기 위해 기존 AWS 배포 시스템의 확장이 필요했습니다. 빌드된 컨테이너 이미지를 AWS ECR과 OpenStack Harbor 양쪽으로 업로드하고, AWS EKS 클러스터 2개와 OpenStack OKS 클러스터 2개에 동시에 배포한 뒤, Istio와 Argo Rollout을 기반으로 점진적인 트래픽 전환이 이루어지도록 배포 시스템을 확장했습니다.

추가로 배포 단계에 클라우드별 자동화 테스트 단계를 추가하여, 클라우드 간 기능과 동작의 차이가 없는지를 지속적으로 검증해서 서비스 안정성을 한 단계 더 높였습니다.
클라우드 부하분산
AWS와 OpenStack을 Active-Active로 운영하기 위해 클라우드 간 트래픽 부하 분산이 필요했습니다. 저희는 AWS Route53 서비스를 이용해 기존 AWS에서 사용하던 IP와 OpenStack에서 새로 추가된 IP를 동시 노출하는 DNS 기반 부하 분산 방식을 사용하기로 했습니다.
하지만 OpenStack의 신규 IP를 DNS에 노출하기 위해서는 고객사 방화벽에 해당 IP를 미리 등록해야 했는데, 이 작업은 시간이 오래 걸리고 확인이 어려워 Active-Active 클라우드 운영 시작이 지연이 되는 문제가 있었습니다. 그래서 저희는 AWS에서 사용 중이던 Global Accelerator 구성을 변경해 AWS와 OpenStack 간 트래픽 부하 분산에 우선 적용해서 Active-Active 클라우드 운영의 시작을 빠르게 할 수 있었습니다.

로그 수집 및 분석
저희는 CDN, Load Balancer, Kubernetes, Istio 등 인프라와 애플리케이션에서 발생하는 초당 약 10만~30만 개의 로그를 수집하고 있고, 수집된 로그는 Elasticsearch에 저장된 후 서비스 분석과 이상 탐지에 활용되고 있습니다.
하이브리드 클라우드 운영 초기에는 대부분의 애플리케이션이 AWS에 있었기 때문에, 로그 저장과 분석에도 기존 AWS 인프라를 그대로 사용했습니다. 그러나 OpenStack에서 동작하는 애플리케이션이 늘어나면서 AWS와 OpenStack을 연결하는 전용선 구간에서 트래픽 병목이 발생했습니다.
그래서 저희는 로그 저장 및 분석을 위한 Elasticsearch 클러스터를 AWS와 OpenStack 각각에 구성하고, Elasticsearch의 Cross Cluster 기능을 이용해 통합 검색, 이상 탐지, Kibana 기반 통합 뷰를 제공하도록 구성해서 전용선 구간의 트래픽 병목을 해결하면서도 서비스 가시성은 계속 유지할 수 있었습니다.

OpenStack에서 AWS 리소스 접근
다음으로, OpenStack 환경에서 S3와 같은 AWS 리소스에 접근해야 하는 상황에서 어떻게 안전하게 사용할 수 있도록 구성했는지 소개하겠습니다.
AWS Roles Anywhere
기존에는 AWS VPC 외부에서 AWS 리소스에 접근하기 위해 AWS IAM에서 Access Key를 발급받아 사용했었습니다. 하지만 Access Key 누출로 인한 보안 사고 위험이 지속적으로 증가하고 있었기 때문에, OpenStack 환경에서는 처음부터 Access Key 없이 AWS 리소스에 접근할 수 있는 방법이 필요했습니다. 그래서 저희는 AWS 의 Roles Anywhere 서비스를 이용해 IAM Role을 사용할 수 있는 환경을 구현하기로 했습니다.

AWS Roles Anywhere는 AWS SDK의 임시 토큰 획득 방법을 이용해서 구현이 되어야하는데, AWS SDK 제한으로 해서 가상서버인 Nova와 OKS 컨테이너에서 서로 다른 방법으로 구현이 필요했습니다.
Nova에서의 구현
먼저 가상 서버인 Nova에서는 AWS SDK의 “프로세서 보안 인증 제공자” 방식을 사용했습니다.

OKS 에서의 구현
다음으로 OKS의 Pod에서는 AWS SDK의 “컨테이너 보안 인증 제공자” 방식을 사용했습니다. 동작 방식은 Pod의 애플리케이션 컨테이너가 Tosspayments Sidecar 컨테이너를 통해 Roles Anywhere Gateway 서비스에 권한을 요청하면, Roles Anywhere Gateway는 Kubernetes Service Account 정보를 조회해 요청의 유효성과 할당된 AWS IAM Role을 확인합니다. 이후 AWS Roles Anywhere로부터 임시 토큰을 받아 전달하는 방식으로 구현했습니다.

Roles Anywhere 보안 강화
OpenStack에서 AWS 리소스를 사용할 때는 모두 AWS Private Link를 통해 전용선으로 접근하도록 구성했지만, AWS Roles Anywhere는 퍼블릭 서비스이기 때문에 OpenStack에서 발급된 AWS IAM 임시 키가 공용 인터넷망에서 사용되지 않도록 차단할 필요가 있었습니다.

그래서 저희는 AWS Roles Anywhere Profile에 설정하는 Session Policy를 이용해, 발급된 임시 키가 aws:VpcSourceIp 조건을 통해 허용된 네트워크에서만 사용 가능하도록 보안을 강화했습니다.

마치며
2명의 시스템 엔지니어로 시작한 도전, "용감하다"는 말과 "미쳤다"는 말을 동시에 들으며 시작한 여정이었습니다. 서버에 라우팅이 1997개나 있고, DNS도 없고, 이중화된 장비끼리도 구성이 다른 레거시 인프라. 그 위에서 안정적인 서비스를 운영하는 것은 불가능해 보였지만 저희는 포기하지 않았습니다:
그 결과 저희는:
2개의 클라우드 인프라와 4개의 K8S 클러스터가 Active로 동작하며 대한민국의 결제를 지키고 있습니다.
토스페이먼츠의 여정은 아직 끝나지 않았습니다. 함께하는 가맹점이 더 빛날 수 있도록, 사업자의 유일무이한 기술 파트너가 되기 위한 고민과 노력이 오늘도 계속되고 있습니다.
✅ 이번 아티클은 아래 Toss Makers Conference의 세션을 바탕으로 재구성되었습니다.
