[Sprint2] 배포를 시작하기 전에 반드시 알아야 할 것들 - 배포 전략
CI/CD 파이프라인 구성시 고려해야 하는 사항
Jenkins Pipeline 구성 여부
이전까지 구성했던 것은 각각의 파이프라인을 따로 실행했던 것인데,
Jenkins Pipeline을 이용해 한번에 연결되는 구조를 만들 수도 있다.
1. 각각의 파이프라인
실무에서는 관리 담당자의 역할을 구분하거나, 처음부터 기능을 만드는 경우에는 분리하는 것이 관리 책임 면에서 좋음
(어차피 트리거를 걸어놓으면 자동 배포가 되는 것은 마찬가지)
2. Jenkins Pipeline
장점
기능적으로 좋음- Jenkins가 시각적인 스테이지 (UI)를 제공함 (일반적으로 좋다)
Jenkinsfile을 릴리즈로 관리할 수 있음 (yaml 파일이나 dockerfile처럼 사전의 스크립트로 Jenkins Pipeline 실행 가능)
(코드의 장점 - 처음에 만들기는 어렵지만 복사 및 변경 이력 관리가 유리함)
Jenkins에서 UI로 만든 구성을 스크립트로 알려주기 때문에 처음에는 UI 구성이 빠를 수 있음
3. 다른 경우
혹은 소스빌드( 개발자) / 컨테이너 빌드. 배포 (Devops 엔지니어) 로 구분할 수도 있다.
=> 기능적 / 관리적 측면을 고려해 무엇이 효율적인지 고려해야 함
4. ArgoCD 사용
배포: 인프라 환경
1:N
장점: 편의성 / 단점: 개발 환경에 장애시 운영환경에도 배포 불가
1:1
장점: 개발 환경 장애시에도 지장 없음 / 단점: ArgoCD 이중 관리 부담
(후자를 더 많이 사용한다)
=> 회사마다 관리 편/장애 영향도 어떤 것을 중시할지에 따라 다르다.
CI/CD 툴
온라인: Github Actions
오프라인: Jenkins, JenkinsX(컨테이너 친화), Tekton(컨테이너 친화)
CI 전용 툴
온라인: Travis CI, Circleci
오프라인: GitLab
CD 전용 툴
오프라인: argoCD, Spinnaker
금융권, 의료기관, 공공기관들은 자사의 시스템이 인터넷 상에 있으면 안되기 때문에 오프라인 툴을 사용해야 한다.
=> 레퍼런스가 많은 것을 선택하기
Github Actions > Jenkins >>> ArgoCD
(국내에서는 Github Actions < Jenkins)
제품을 도입하고 유지보수하는 것도 고려해야함
Docker의 대체
Docker의 단점
1. 무겁다(자원을 많이 사용함)
2. Deamon이 필요하다
(컨테이너 빌드 속도가 느린 것은 아님)
도커로 컨테이너를 여러 개 띄웠는데 도커 데몬이 죽으면 모든 컨테이너가 같이 다운 됨
CI/CD에서 컨테이너 빌드용으로만 사용하면 문제 되지 않음
CI/CD 서버에서는 컨테이너를 띄워놓을 일이 없다
=> 자원 사용량이 중요하면 buildah+podman+skopeo+argoCD 고려(Openshift같은 관리형 k8s 제품에 기본적으로 포함됨)
buildah: 컨테이너 빌드(Deamoless)
podman: docker 로그인 및 이미지 가져오기
skopeo: 이미지 푸시
배포 전략을 세울 때 고려해야 하는 요소
1. Recreate
- 배포 작업
: Deployment 업데이트
- 특징
자동 배포(정지, 롤백 가능)
- ⚠️단점
트래픽 제어 불가
- 사용 툴
kubernetes, helm, kustomize
2. RollingUpdate
- 배포 작업
: Deployment 업데이트
- 특징
자동 배포(정지, 롤백 가능)
무중단 서비스 배포
- ⚠️단점
트래픽 제어 불가
- 사용 툴
kubectl, helm, kustomize
3. Blue/green
- 배포 작업
1. v2 버전의 Deployment 생성
2. Service의 selector를 v1->v2로 수정
3. v1 버전의 Deployment 삭제
- 특징
수동 배포시 롤백이 빠름(1초만에! - RollingUpdate는 3~4분 걸림)
Script를 통해 자동 배포 가능
- ⚠️단점
v2에 과도한 트래픽 유입시 문제 발생(처음 트래픽시 메모리나 DB Connection들을 최적화 하느라 CPU 사용량이 느는데, 이 시점에 Blue/Green 배포시 서비스가 중단될 수 있음)
=> 미리 부하 테스트를 하는 것이 필요
- 유즈 케이스
운영 환경에서만 테스트가 가능한 경우
ex) 금융기관, 공공기관 등 => 개인정보가 있는 경우에는 운영 DB에만 데이터가 있어야 하기 때문
v2 Deployment를 생성해놓고 새 서비스를 v2 Deployment에 연결해서 테스트함-> 문제 없으면 v2로 전환
- 배포 툴
kubectl, kubernetes, ArgoCD
4. Canary
- 배포 작업
1. v2 버전의 Deployment, Ingress, Service 생성 ( Ingress Controller(Nginx)는 사전에 설치)
2. v1, v2의 Ingress 가중치 변경
3. v2로 트래픽 전환이 모두 끝나면 v1 버전의 Deployment, Ingress, Service 삭제
- 유즈 케이스
특정 헤더 값에서만 한해 v2로 트래픽을 유입시킬 때
헤더 값 정보 - IP, User, Language
- 특징
콜드 스타트 방지
=> 10%의 트래픽만 유입시켜 보면서 새 버전에 문제가 있는 지 확인 가능하다.
=> 메모리와 DB Connection 상태가 최적화 된 후에 나머지 트래픽이 붙음
두 버전 비교 가능( A/B 테스트: Canary 배포 상황에서의 테스트 방법론 중 하나)
- 배포 툴
ArgoCD, Nginx, Istio
기존 운영 환경에서 배포해왔던 방식
L4 네트워크 장비 - VM1
- VM2
이중화 시켜서 사용
- 배포 작업
1. VM2의 연결 해제
2. VM2에 소스 패치 밒 기동 설정
3. L4 담당자가 트래픽 변환
이때, V1을 먼저 끊고 V2를 연결 -> Recreate
V2를 먼저 연결하고 V1을 해제 -> RollingUpdate
보통 VM1을 끊음과 동시에 V2를 연결함
이후 VM1도 패치 후 다시 이중화 구성
=> 현재는 kubernetes 사용으로 네트워크단 장비를 건드리지 않고 Blue/Green 배포가 가능하다.
그럼 어떤 배포 전략을 사용해야 하는가?
무조건 서비스 중단이 없이 배포해야 하는 것은 아님!
데이터베이스 스키마 변경 시 DB 작업이 끝나고 v2 버전을 올려야 하기 떄문에 사전에 서비스 중단 공지 후 수동으로 배포해야 함
1. 서비스 중단 공지
2. replicas=0 으로 서비스 내림
3. DB 작업
4. deployment의 image 태그를 v2로 변경
5. replicas를 2로 수정
단계별로 구축해보는 배포 파이프라인
실무에서도 프로젝트를 할 때 간단히 파이프라인을 구성한 후 업그레이드 하는 방식이 좋음
=> 당연하게 연결 될 줄 알았던 Docker, kubernetes 통신 등이 안 될 때가 많기 때문
=> 단계적인 작업을 거치는 것이 리더의 입장에서 신뢰를 줌(작업 과정이 보이는 것이 중요)
=> 중간 과정이나 결과를 보여주지 않으면 리더의 입장에서 불안하고, 결과물에 대한 믿음이 생기지 않음!!
1단계
현재까지 진행한 내용
2단계
Jenkins Pipeline 구성
3단계
helm, kustomize 사용 => yaml 파일들을 동적으로 구성
동적 구성의 장점
name이나 selector 부분에 변수를 입력함으로써 수정이 간단하고 실수를 줄여준다.
특히 30~40개의 앱을 배포시에는 필수적이다.
하지만, 만들기가 복잡하기 때문에 단계 2를 거치는 것이 좋음
4단계
ArcoCD로 배포 분리
ArcoCD가 형상 관리를 해주면서 k8s에 배포한 yaml 파일들과 Github의 형상관리 파일들을 동기화시켜줌
배포=릴리즈 파일 수정
ArcoCD 장점
1. 문서와 실체를 동일하게 유지
2. Kubernetes 리소스를 편하게 볼 수 있는 UI 제공(kubernetes 대시보드 보다 좋음)