[CI/CD] GitOps 환경 구축하기(1) GitOps, Kubernetes

우노·2024년 9월 15일
0

Practice & Trouble Shooting

목록 보기
14/20

최근 팀프로젝트를 시작해서 클라우드 담당으로서 다양한 삽질을 하기 시작했다. 자동화된 빌드/배포 환경을 처음부터 만든다거나 테라폼으로 AWS 인프라를 생성했다 삭제하기를 반복하고 쿠버네티스로 서비스를 배포하려고 부딪혔다. 트러블 슈팅에 밤새 시달리다가 자고 일어나서 아침이 되니 한 시간만에 해결하기를 반복했지만 90DaysOfDevOps를 보며 말로만 이건 이렇고 저건 저렇다 비교했던 서비스를 직접 사용해보며 기술 비교가 겉핥기식 보다는 조금 나아진 것 같다. 그리고 되돌아보면 GitOps로 CI/CD를 일찍부터 적용해둬서 혼자 클라우드를 담당했음에도 살아남을 수 있었던 것 같다.

하지만 여전히 어렵다. 좋게 말하자면 Learning By Doing, 다르게 말하자면 맨땅에 헤딩.. 이제 왜 이걸 써야하는지에 대한 분석과 더 나은 방법은 없는지를 고민해야할 것 같다. 그럼 이번 프로젝트에서 활용하면서 배웠던 GitOps와 쿠버네티스 CI/CD 자동화 과정에 대해서 이야기해보려 한다.

GitOps란?

GitOps는 기존 프로젝트 코드 뿐만 아니라 IT 인프라에 Git을 적용하여 버전/형상 관리를 하는 DevOps 적용 방식이다. IaC로 IT 인프라를 구축하고 Git으로 관리하는 등 효율적인 클라우드 네이티브 인프라 관리를 가능하게 한다. 간단히 말해 인프라 구성부터 CI/CD 자동화 등의 운영 과정을 코드로써 선언적으로 관리하고 이를 Git으로 통합/관리하는 방식이다. 물론 CI/CD라고 했지만 환경에 종속적이지 않아야하는 CI보다는 CD에 중점적으로 적용된다.

선언형

여기서 알 수 있는 GitOps의 가장 큰 특징은 선언형이라는 점이다. Git의 본래 목적과 용도는 여러 개발자가 한 프로젝트 코드에서 동시에 작업하고 변경 내용을 효과적으로 병합하고 관리하는 것이다. 이와 동일하게 배포 인프라 구성과 지속적 배포 매니페스트를 코드로 선언하고 Git으로 관리하여 운영에 적용한 것이다.

push vs pull

GitOps의 배포 전략은 push와 pull로 나뉜다. 나는 프로젝트에서 Jenkins로는 push type을, ArgoCD로는 pull type을 활용하였다.

push type

push는 수정사항이 생기면 배포 파이프라인을 실행시키는 것이다. 예를 들면 Git 저장소에 업데이트가 생기면 빌드 파이프라인을 트리거하여 CI/CD 과정을 시작하게 된다. 이를 Jenkins , CircleCI 또는 Travis CI 등의 CI/CD 툴로 구현할 수 있다.

나는 Github Webhook에 Jenkins 주소를 등록하여 업데이트가 생기면 등록한 주소로 알림이 가서 빌드 파이프라인을 트리거하게 구성했다. CI가 성공적으로 끝나면 파이프라인 마지막에 Github 매니페스트 레포지토리의 이미지 태그를 수정하는 스테이지를 넣어 CD 파이프라인을 트리거했다.

pull type

pull은 현재 배포 인프라 상태와 저장소에 선언된 상태를 지속적으로 모니터링하고 비교하여 파이프라인의 역할을 대신한다. 두 상태에 차이가 생기면 인프라를 업데이트하여 상태를 일치시킨다. 이미지 레지스트리를 모니터링하여 새 버전을 감지할 수도 있다.

나는 클러스터에 ArgoCD를 설치하고 애플리케이션 상태를 선언한 yaml 파일을 관리하는 매니페스트 레포지토리를 두어 ArgoCD에 등록했다. 이를 통해 CD 파이프라인을 통해 매니페스트 레포지토리의 이미지 태그가 변경되면 ArgoCD가 이를 추적하여 OutOfSync를 표시하고 상태를 맞출 수 있도록 한다.

장점

Deploy Faster More Often

CI/CD가 중요한 이유는 빠르게, 자주 수정 사항이 반영되는 MSA 환경에서 수정 사항을 배포에 에러 없이 신속하고 정확하게 효율적으로 반영해야하기 때문이다. 알잘딱깔센?

Git에 선언된 코드로 CI/CD 자동화를 관리하면 휴먼 에러를 줄일 수 있고 자동화 그 자체로 수정 사항 반영에 소요되는 시간을 줄일 수 있다. GitOps는 빠르게, 자주 변경되는 코드에 맞추어 배포를 맞출 수 있게 한다.

Easy and Fast Error Recovery

프로젝트 코드 관리에서 Git 장점과 동일하게 운영에서 버전 관리가 가능해진다. 즉, 에러 롤백도 쉬워진다. 운영에서 알림과 모니터링을 중요시하는 것처럼 개발보다 배포에서 문제가 생겼을 때 더욱 빠른 대응이 필요하고 일단 빠르게 정상화시켜야하는 상황이 대다수다. 이런 상황에서 Git으로 관리하면 이전 기록으로 되돌리기가 매우 수월하다.

Easier Credential Management

단적인 예로 개발과 운영의 협업 상황을 제시해보겠다. 개발팀이 로컬 DB를 사용하다가 RDS에 연결해야하는 경우가 생겼다고 가정해보자. 그렇다면 개발자는 인프라를 관리하는 팀에 "지금 RDS 있나요?"를 묻고 IAM 계정을 물어 콘솔에 접속하여 상태를 직접 확인해야한다.

여기서 문제는 잘못된 IAM 권한으로 개발자가 인프라 구성을 수정하는 실수를 할 수 있고 개발팀이 개발에 집중하지 못하고 인프라 구성에 쓰는 시간이 늘어나게 된다. 이런 상황에서 테라폼으로 인프라를 구성하고 코드를 저장한 레포지토리를 개발자가 공유했다면 개발자는 해당 레포지토리에서 RDS의 유무와 상태를 바로 확인하고 운영팀에 적절하게 요청할 수 있다.

Self-documenting Deployments / Shared Knowledge in Teams

개발-운영 뿐만 아니라 운영팀 내에서도 각자 수정한 사항을 콘솔에 접속하지 않고도 기록과 코드로 확인할 수 있고 팀 내 상황 공유, 에러 발생 시 재현과 공유로 재발 방지도 가능해진다.

Kubernetes

GitOps 적용에는 꼭 쿠버네티스를 써야하는가? 그건 아니다. Git에 코드가 올라가 있다면 이를 변경할 필요없이 CI/CD 구성을 시작할 수 있다. 레포 내에 있는 쉘스크립트를 활용하여 배포를 하는 것도 GitOps라고 할 수 있다.

하지만 쿠버네티스가 모든 리소스를 코드와 파일로 관리할 수 있어 GitOps의 선언형 방식에 가장 적합하고 이 때문에 pull 배포 전략은 대부분 쿠버네티스를 전제로 하여 만들어진다.

구성

나는 아래와 같이 배포 환경을 구성하고 이를 바탕으로 CI/CD를 자동화하였다. 자세한 이야기를 다음 Jenkins, ArgoCD 글에서 이어질 예정이다.

처음 배포를 구성하면서 아쉬운 점이 많다.. 앞으로 어떤 리소스가 왜 추가되어야하는지 꾸준히 고민하고 싶다. CKA 화이팅(?)

마무리

처음에는 서버비 지원이 나오는만큼 지금까지 못 써본 서비스 전부 써보고 CI/CD를 완전 자동화해보자는 막연한 포부로 GitOps 환경을 구축하기 시작했지만 프로젝트 중, 그리고 끝나고 나서 생각해보니 혼자 클라우드를 담당하는 상황에서 선언형으로 관리하는 GitOps를 적용하니 딸깍 한 번으로 자동화된 빌드부터 배포까지의 과정을 지켜보는 입장으로 에러에 대응할 수 있었다는 걸 실감했다. 선언적으로 관리하는 GitOps 덕분에 에러 원인을 비교적 빠르게 찾을 수 있었고 자동화된 CI/CD를 빠르게 적용하여 중간중간 문제가 생기면 해결하는 정도로 대처할 수 있었다. 배포 환경에 문제가 생겨도 일단 간단하게 롤백하고 트러블슈팅을 할 수 있어서 개발팀에 큰 지장을 주지 않을 수 있었다. 물론 정말 이해하고 필요에 의해 선택해서 사용했다기 보다는 단순하게 한 번 사용해봤다는 느낌으로 그쳐서 아쉬움이 크다.

그래도 결론적으로 일찌감치 적용해둔 CI/CD 덕분에 혼자여도 살았남았다..고 표현하고 싶다.

출처

GitOps에 대해서 더 알고 싶다면 아래 gitops.tech의 글을 자세히 읽고 더 찾아보는 것을 권한다.
[gitops.tech] gitops
[VMware] gitops

부족하거나 잘못된 부분이 있다면 편하게 조언, 지적 부탁드립니다. 🙇🏻‍♀️

profile
기록하는 감자

0개의 댓글