Kubernetes 기반의 어플리케이션 배포 시스템 구축 방법
DevOps 는 개발자와 운영자의 역할을 함께 수행하는 것으로 개발과 운영의 책임을 공동으로 진다. 처음 이 단어를 접한 것이 2011년 OpenStack Summit 에 참석했을 때인데 클라우드, 그 중에서 IaaS(Infrastructure as a Service)가 널리 퍼지기 시작했을 때다. DevOps 는 클라우드 기반에서 빠르게 개발하고, 배포하고, 운영하기 위해서 스타트업 회사를 중심으로 빠르게 퍼지기 시작했다.
아래는 클라우드 가상머신 기반의 DevOps 영역 중 CI/CD 에 대한 프로세스이다. 개발 언어는 Java 를 기준으로 표현하였으며, 이하 모든 설명은 Java 를 기준으로 설명한다.
문제
2015년 7월 쿠버네티스 1.0 버전이 릴리즈 되면서 DevOps 는 가상머신이 아니라 컨테이너 기반으로 점차 변화하였다. 쿠버네티스 이전의 Ops는 가상머신을 빠르게 만들고 개발된 소스 코드를 자동으로 통합 빌드하여 배포하는 영역이었다. 하지만 쿠버네티스가 나오고, 컨테이너 관리가 효율적/안정적으로 변하면서 Ops 는 소스 코드 통합 빌드, 컨테이너 이미지 만들기와 쿠버네티스에 배포, 운영하는 영역으로 바뀌었다. 즉, Ops 영역을 맡은 운영자는 컨테이너도 알아야 하고, 쿠버네티스도 알아야 한다는 의미이다.
결국 쿠버네티스 기반의 DevOps 는 소스 코드 개발, 통합 빌드, 컨테이너 이미지화, 배포의 영역 모두를 의미한다. 이를 간략하게 프로세스로 표시하면 다음과 같다.
여기서 부터 문제가 발생한다. 기존의 Dev 역할은 인프라스트럭처가 가상 머신이든 쿠버네티스이든 상관이 없지만 Ops 역할은 컨테이너와 쿠버네티스라는 새로운 기술을 알아야 하는데 해당 기술을 습득하기까지는 어느 정도의 기술 허들을 넘어야 하고 일정 기간이 지나야 한다. (클라우드 기술이 널리 퍼지기까지 기간을 생각해 보면 쉽게 이해될 것이다)
또한 배포 영역을 생각해 보면 결코 쉬운 문제가 아니다. 배포 전략에는 아래와 같은 3가지 방법이 존재한다. (크게는 4가지 이지만 가장 단순한 Recreate 배포는 생략하였다)
- 이미지 출처: 쿠버네티스 패턴 (책만출판사)
사족이지만 카나리아 배포를 “까나리”라고 발음하지 말자. “까나리”는 액젓이다.
해결책
개발자는 개발의 영역 즉, Dev 영역에 집중하게 하자. 어려운 Ops 영역은 시스템으로 자동으로 동작하도록 제공하자.
앞서 간단히 살펴본 개발/배포 프로세스를 다시 살펴보자.
- 개발자가 IDE 툴을 통해 프로그램을 개발한다.
- Maven 혹은 Gradle 로 소스 코드를 빌드한다. 로컬 빌드, Jenkins 혹은 기타 다른 CI 툴을 활용한 빌드 결과물로 jar 혹은 war 파일이 생성된다. 일반적으로 스프링 부트 프로젝트는 jar 파일로 만들어지며, war 파일은 일반 스프링 프로젝트이다. 해당 결과 파일은 저장소(e.q. nexus)에 저장된다.
- jar 혹은 war 파일을 로컬 빌드 혹은 기타 다른 CI 툴을 활용하여 컨테이너 이미지로 빌드한다.
- 빌드된 컨테이너 이미지를 이미지 저장소에 저장한다.
- 쿠버네티스에 배포하기 위해 deployment.yaml, service.yaml 등을 포함한 helm chart 를 만들고 이를 서버에 배포한다. 배포할 때는 배포 전략에 따라서 Rolling update, Blue-Green, Canary 로 배포한다.
1번과 2번은 개발자가 이제까지 하던 방식 그대로 개발하면 된다. 우리가 시스템으로 만들어 제공해야 할 부분은 3, 4, 5 번 영역이다.
구현 방법
해당 시스템에 대한 아키텍처를 구성하면 다음과 같다.
사용 오픈소스 S/W
- Nexus
- Maven 저장소로 사용되며 테스트 용도의 jar 파일을 저장하고 다운로드 할 수 있음
- Keycloak
- 인증 서버로 활용
- OIDC 접속 백엔드로 활용할 수 있음
- Argo Workflow
- CNCF Graduated Project
- 워크플로우 서버로 파이프라인을 설계하고 실행할 수 있음.
- 워크플로우 템플릿을 작성하면 재사용 가능함
- 워크플로우 실행은 컨테이너 단위로 실행됨
- Harbor
- CNCF Graduated Project
- 이미지 저장소로 활용
- Gitea
- Helm chart 저장소로 활용
- Helm
- Helm chart template 관리
- Argo Rollout
- 배포 전략을 다양하게 지원함
- 지원 배포 전략: Rolling update, Blue-Green, Canary
프로세스 설명
- 사용자는 cli (golang)로 앱 배포를 요청한다.
- API 서버 (golang) 는 해당 요청을 받아서 Argo workflow 를 호출한다.
- Argo Workflow 에서 Nexus 로 부터 jar 파일을 가져온다.
- Argo Workflow 에서 jar 파일을 컨테이너 이미지 파일로 빌드하고 이미지 저장소인 하버에 저장한다.
- Argo Workflow 에서 이미지를 가져온다.
- Argo Workflow 에서 Helm chart 템플릿을 가져온다.
- Argo Workflow 에서 Helm chart 와 이미지를 조합하여 Argo Rollout 으로 배포한다.
- Argo Rollout 은 초기 배포를 Blue 로 배포한다. 배포된 Blue 는 로드 발랜서와 연결된다.
- 사용자가 Cli 로 앱 업그레이드를 Blue-Green 전략으로 요청한다.
- Argo Workflow 에서는 Rollout 으로 Green 으로 배포한다.