이번 글에서는 보안 강화를 위해 개발 서버를 Public 환경에서 Private 환경으로 전환하며 발생한 CI/CD 배포 파이프라인의 문제점과, 이를 해결하기 위해 Github Action Runner를 도입한 과정을 정리한다.
1. 배경 및 문제점
기존 CI/CD 아키텍처는 Github WebHook과 Jenkins를 활용한 구조였다. GitHub에서 Push 이벤트가 발생하면 WebHook을 통해 Jenkins 서버로 알림을 전달하고, Jenkins가 이를 감지하여 개발 서버에 배포하는 방식이었다.

하지만 기존 Public이었던 개발 서버를 Private 환경으로 변경하면서 외부에서의 인바운드 트래픽이 모두 차단되었고, 결과적으로 GitHub에서 보내는 WebHook 요청을 서버가 수신할 수 없는 상황이 발생하였다.
즉, 기존의 배포 자동화 프로세스가 동작하지 않게 되어 새로운 대안이 필요한 상황이었다.
2. 해결 방안 모색
[ 방화벽 정책 변경 (Github IP 허용) ]
가장 먼저 고려한 방법은 GitHub WebHook이 사용하는 IP 대역만 방화벽에서 허용하는 방식이었다.
하지만 GitHub의 WebHook 요청 IP는 고정된 하나의 IP가 아닌 다수의 IP 가 존재하여, 매 요청마다 IP 가 유동적으로 변경되어 서버에 요청을 전송하고 있다는 것을 확인할 수 있었다. 결국 GitHub의 모든 IP 를 추적하여 관리하는 것은 현실적으로 어려웠고, 보안을 위해 Private으로 전환한 취지에 맞지 않게 너무 많은 IP를 허용해야 한다는 점에서 보안상 좋지 않다고 판단하여 해당 방법은 채택하지 않았다.
[ 주기적 폴링 스크립트 ]
다음으로 고려한 방법은 서버 내부에서 스크립트를 작성하여 주기적으로 GitHub 원격 저장소의 변경 사항을 감시하는 방식이었다.
하지만 해당 방식은 코드가 변경되는 즉시 배포되는 실시간성이 보장되지 않는다는 문제가 존재하였다. 또한, 해당 스크립트가 백그라운드에서 정상적으로 동작하고 있는지 확인하기 위한 별도의 모니터링 시스템을 추가로 구축해야 한다는 리소스 낭비가 발생하여 해당 방법 또한 채택하지 않았다.
3. 기술적 의사결정
최종적으로는 Github Action Self-hosted Runner를 활용하는 방안을 채택하게 되었다.
3.1. 아웃바운드(Outbound) 트래픽 활용
Self-hosted Runner는 서버 내부에 설치된 Runner 애플리케이션이 GitHub 서버와 통신을 유지하는 방식이다. 해당 방식은 외부에서 들어오는 인바운드 트래픽이 아니라, 서버 내부에서 GitHub 쪽으로 나가는 아웃바운드(Outbound) 트래픽을 사용하여 이벤트를 감지하기 때문에 Private 서버의 방화벽 인바운드 정책을 열지 않고도 GitHub의 Push 이벤트를 실시간으로 감지할 수 있어 보안 문제를 해결할 수 있었다.
3.2. 운영 및 모니터링의 편의성
또한, Runner는 GitHub Action 과 연동하여, GitHub 내에서 Runner 의 구동 상태와 배포 성공/실패 여부를 직관적으로 확인할 수 있어 별도의 모니터링 시스템을 구축할 필요가 없다는 이점이 존재하였다.
4. 마무리
결과적으로 Github Action Self-hosted Runner를 도입함으로써, Private 네트워크 환경에서도 실시간 CI/CD 파이프라인을 성공적으로 구축할 수 있었다.
사실 Kubernetes(K8s) 환경이었다면 ArgoCD를 활용한 GitOps 방식을 도입하는 방식도 존재하였다. 하지만 당시 상황은 빠른 구현이 필요했고, 팀원 전체가 ArgoCD에 대한 러닝 커브를 감당하기에는 시간이 부족했기 때문에 도입하지 않았다.
추후 프로젝트 안정화 이후에는 ArgoCD 도입을 검토하여 현재의 Runner 방식을 리팩토링하고, 이를 통해 GitOps 체계로 고도화하는 과정을 별도의 포스팅으로 남겨보는 것도 좋을 것 같다.