Github Action + Jenkins on k8s + ArgoCD

푸르둥개·2025년 11월 20일

팀원의 세미나 자료 공유

CI/CD 개념

CI/CD란 간단하게 말해서 어플리케이션 개발부터 배포까지의 모든 단계들을 자동화를 통해 효율적이고 빠르게 사용자에게 빈번이 배포할 수 있도록 만드는것을 말합니다.
CI 는 Continuous Integration 지속적인 통합의 약자이고,
CD는 Continuous Delivery 지속적인 제공의 약자입니다. Delivery 대신 Deployment(배포)로 사용하는 경우도 있습니다.

Continuous Integration (지속적인 통합)

지속적인 통합이란 버그 수정이나 새로 만드는 기능들이 메인 repository에 지속적으로 merge되고 build 되는것입니다.

중요한 두가지 포인트로는
첫번째, 코드 변경 사항을 주기적으로 빈번하게 Merge 해야한다.
두번째, 통합을 위한 단계(Build, Test, Merge)의 자동화가 필요하다.
는 점이 있습니다.

주기적으로 merge된 코드의 변경사항이 자동으로 build되어서 코드의 변경 이후에도 build가 성공적으로 되는 지 확인되어야 합니다. 추가적으로, 변경된 사항이 기존 시스템의 다른 버그를 초래하지는 않았는지 자동으로 테스트까지 되어야 합니다.

CI 원칙을 따르면 주기적으로 merge되기 때문에 다른 코드와의 충돌을 피할 수 있어 생산성을 더 높일 수 있습니다. merge되는 코드들은 자동으로 build + test 되기때문에 코드의 결함이 빠르게 발견되어질 수 있다는 장점이 있습니다. 또한 이렇게 발생되는 결함은 빠르게 수정이 가능하다는 장점이 있습니다. 이렇게 운영함으로써 조금 더 나은 코드의 퀄리티를 가져갈 수 있는데요, 이렇게 CI를 잘 운영하기 위해서는 모든 개발자들이 자신이 개발한 코드에 한해서는 반드시 유닛테스트를 포함해야 하기 때문입니다. 이로써 조금 더 안정성 있는 제품을 개발해나갈 수 있습니다.

Continuous Delivery(Deployment) (지속적인 제공)

지속적인 제공’과 ‘지속적인 배포’ 이 두가지 모두 마지막 배포 단계에서 어떻게 하면 자동화를 통해 배포를 만들어나갈 수 있을지 고민하는 단계입니다.

CI를 통해서 주기적으로 merge된 코드의 변경사항들이 자동으로 build + test 되고 나면, 이제 배포하는 단계에서 release 준비 과정을 거치고 release에 아무런 문제가 없고 정상적인지 직접 개발자나 검증팀이 검증한 다음, 사용자에게 배포해도 되겠다 라고 검증되면 수동적으로 배포하는 단계를 Continuous Delivery라고 합니다. 또는 release가 준비되자마자 자동으로 사용자에게 배포되도록 모든 과정을 자동화 해놓는것을 Continuous Deployment라고 합니다.
Delivery와 비슷하지만 최종 단계가 자동화되었는지에 따라서 달라질 수 있습니다.


Jenkins 개념

Jenkins란 앞서 설명한 CI/CD의 환경을 구축하기 위한 오픈소스 자동화 도구입니다. Jenkins와 같은 CI 툴이 등장하기 전에는 일정 시간마다 빌드를 실행하는 방법이 일반적이였지만, Jenkins의 등장으로 Git과 같은 버전 관리 시스템과 연동해서 코드의 변경사항을 감지하여 자동으로 테스트가 포함된 빌드가 가능하게 되어 편의성이 증가되었습니다.

Jenkins Plugin

Jenkins는 사실 Java로 작성된 단순 서버입니다. Jenkins의 가장 핵심 기능인 Pipeline 조차도 플러그인이며, 온갖 종류의 개발 작업을 지원하기 위한 약 1,400여가지의 플러그인을 가지고있어 각각의 환경에 맞는 VCS(버전 제어 시스템)와 빌드 툴을 선택해 입맛에 맞게 사용할 수 있습니다.

Jenkins의 장점

다양한 유연성과 확장성: Jenkins는 다양한 플러그인을 제공하여 프로젝트에 필요한 다양한 작업 및 통합을 구성할 수 있습니다. 이로 인해 프로젝트 요구사항에 맞게 맞춤화된 자동화 프로세스를 구축할 수 있습니다.

커뮤니티와 생태계: Jenkins는 큰 오픈 소스 커뮤니티와 생태계를 가지고 있어서 다양한 플러그인, 라이브러리, 지원 자료 등을 활용할 수 있습니다. 이로써 다양한 상황에 맞게 Jenkins를 확장하고 개선할 수 있습니다.

분산 빌드와 스케일링: Jenkins는 여러 빌드 에이전트를 사용하여 병렬로 빌드 및 테스트를 실행할 수 있어서 대규모 프로젝트에서도 빠른 처리가 가능합니다.

As - Is Flow 소개 (Jenkins + Rancher)

현재 Dev와 Stage 환경에서는 담당자의 로컬에서 docker-compose.yaml 파일을 빌드하여 Rancher로 배포하는 방식을 사용하고 있습니다. 여러대의 서버에, 그리고 각각 다른 서비스 지역별로 배포를 진행하는데에 적게는 몇분에서 길게는 몇시간까지도 소요될 수 있고, 서버 여러대에 배포하는 중간에 결함이 발견되면 다시 하나하나 롤백을 진행한 후 문제지점을 찾고, 수정하고, 수동으로 테스트 하고, 다시 빌드한 후, 또다시 여러대의 서버에 배포를 진행합니다. 어떤 날은 배포하는데 하루가 다 가버리기도 합니다.

To - Be Flow 소개 (Github Action + Jenkins + ArgoCD)

Github Action + Jenkins + ArgoCD를 사용한 배포 프로세스로 개선된다면, 개발자가 Github에 Code를 Push(사용자가 지정한 이벤트)하기만 하면, Github의 webhook이 동작하여 Jenkins 에게 “코드에 변경사항이 생겼으니 빌드를 진행하라”라고 요청을 보냅니다. Jenkins는 요청을 받아 Github에서 새로운 코드를 내려받은 후, 동적으로 Pod를 생성해 Build와 Test, Image Push 작업을 진행합니다. 빌드된 이미지는 Harbor에 저장되고, Jenkins가 manifest.yaml(우리팀의 경우에는 CI/CD 리포지토리)에서 이미지 태그의 버전부분을 갱신합니다. ArgoCD는 일정한 주기로 manifest 파일을 지켜보다가 변경사항이 생기면 sync를 맞추는 작업(새로운 버전 배포)을 실행하게 됩니다. 배포가 완료되면 Openlens나 Kube Rancher를 통해 버전이 변경된 것을 확인할 수 있습니다.

정리하자면, 개발자는 Main 브랜치나 Develope 브랜치에 코드를 Merge(or Push)하기만 하면 배포가 완료되는 것입니다!

Jenkins의 다양한 플러그인

  • 플러그인 관리 (UI 상 플러그인 매니저 → yaml 형태로 관리)

빌드툴 관리

  • Security 관리
  • Library 관리
  • Agent pod template

공통 설정 관리

Github Webhook 설정

젠킨스(Jenkins) GitHub Webhooks 연동

Jenkins Generic Webhook Trigger를 이용한 GitHub branch별 push event WebHook 설정

[Bridge][오류해결] 기준 브랜치 변경 후 자동배포가 안되던 상황

Jenkins 파이프라인 실행 결과

Git에서 소스를 받아 해당 소스를 Dockerfile로 빌드한 후, Harbor에 Push하는 파이프라인을 작성합니다.

[DevOps] 7. jenkins를 통한 GitHub 소스배포 및 Docker build, run 자동화(1) - 실패 및 Error에 관한 정리

Docker Out of Docker (DooD)

How to Setup Jenkins Build Agents on Kubernetes Pods

Jenkins 버전 업그레이드 이후 에러 해결. 플러그인간 버전 불일치로 Docker를 실행하는 플러그인이 제대로 동작하지 못하여 발생한 에러

파이프라인 실행 성공

Openlens로 동적 Pod 생성 확인


Name hello-kgrmg-mdwjd 라는 Pod가 생성되는중


동적으로 생성된 Pod의 Status가 Running이며, 파이프라인이 실행되고 있다.

작업이 끝난 후 Pod가 종료되고 컨테이너가 사라진다.

Kubernetes의 이벤트 로그 확인

Harbor에 Push한 이미지 확인

고민

  • 우리 서비스가 작은 서비스라면 현재와 동일하게 Rancher를 사용하거나, Docker base로 Jenkins를 실행해도 크게 문제가 되지 않습니다. 하지만 우리는 글로벌 서비스로 나아가야하고, 지금보다 더 많은 서버와 자원을 사용해야 하기 때문에 새로운 방법으로의 구축이 필요합니다.
  • 사람들이 Docker 위에서 동작하는 Jenkins에서 Github Action으로 발길을 돌리고 있습니다. 왜냐하면 Docker 위에서 동작하던 Jenkins가 여러개의 빌드를 동시에 수행하다가 죽어버리는 경우가 매우 잦고, 항상 리소스를 100% 대기시켜두다가 빌드할 때 1~2% 정도만 사용하는데 유휴자원이 98% 이상인 시간이 대부분이라 리소스 낭비가 심각하기 때문입니다. 하지만 Jenkins On Kubernetes 를 사용하여 동적으로 Pod를 생성하는 방식을 적용하면, 위에 언급한 문제들은 해결되고, 리소스를 동적으로 사용할 수 있게 되기 때문에 빌드를 하지 않을때는 리소스 사용량을 1% 미만으로까지 줄일 수 있습니다.
    Github Action은 분명한 장점(자체적으로 빌드, 테스트, 동적분석 가능)을 가지고있지만, 일정 사용량을 넘어가면 유료로 전환이 되고, 외부 Tool 을 연동하는데에 매우 보수적이기 때문에 한정된 기능만 사용할 수 있다는 단점이 존재합니다. 반면 Jenkins는 1400개 이상의 플러그인을 통해 각자 프로젝트에 맞게 배포 프로세스를 개선할 수있다는 장점이 있습니다.
  • 처음 조사를 진행할때는 Github Action VS Jenkins 와 같이 둘중 하나만 선택해서 사용한다는 글이 많았습니다. 둘 다 사용할수는 없을까? 라는 생각으로 시작해 우리 회사에 적합한 Flow를 아래와 같이 그려보게 되었습니다. Docker Image Build를 기준으로 이전에 수행해야할 작업과 이후에 수행되는 배포 작업이 존재합니다. 빠르고 인증 절차가 까다롭지않은 Github Action에서 어플리케이션 Build, Test, Test Code 실행, 정적 코드 분석 등을 실행하고, 코드리뷰 후에 Merge되면, Jenkins가 요청을 받아 자동으로 Docker Image Build, Push, Git Ops Update를 진행하여 배포가 완료됩니다. 두가지의 툴의 역할이 바뀌어도 상관없습니다. 한가지 툴에만 의존하여 비용이 발생하는것 보다는 역할을 나누어 비용부담을 줄이고, 담당자들의 관리가 편리해지도록 합니다.
  • 모든 프로젝트에 적용하는것이 현실적으로 힘들수 있습니다. 담당자분들이 함께 고민해보면 좋겠습니다.

참고


profile
DevOps, 개발팀과 운영팀이 알아두면 좋은 정보를 공유합니다.

0개의 댓글