DevOps/DevOps

[GCP] Docker와 Cloud Build & Cloud Run CI/CD

sebinChu 2023. 10. 30. 16:56

개요

CI/CD 구축의 핵심 과정인 Google Cloud Build와 Cloud Run을 세팅하는 과정에 대해 알아보자.

 

 


1. Google Cloud Build 설정하기

 

Google Cloud Build란?

Google Cloud Build는 Google Cloud 인프라에서 빌드를 실행하는, 말 그대로 빌드 서비스다. 사용자가 세팅한 Trigger가 발생하면 Github, Cloud Storage 등등에서 소스 코드를 가져오고, 사양에 맞게 빌드를 실행한다. 즉, CI(Continuous Integration - Build & Test & Merge)를 담당하는 도구이다. Docker Container나 Java Archive와 같은 도구를 통해 Artifact(빌드 결과물)를 빌드하도록 설정할 수 있다. 

 

Google Cloud Build의 CI 동작 과정

 

1. Cloud Build의 빌드 트리거에 사용자가 설정한 코드 변경이 감지된다.

2. 코드 변경을 감지한 Cloud Build는 빌드 환경을 설정한다. 이때 빌드 환경은 Docker Container와 빌드 구성 파일(cloudbuild.yml)을 기반으로 설정된다.

3. 빌드 환경이 설정되고 난 후, 빌드 구성 파일에 담긴 명령어를 순서대로 실행한다. 여기서 Docker Image 빌드 관련 설정이 시작된다.

 

 


1-1. IAM 사용자 권한 설정

 

 

Cloud Run에 배포하기 위해서 Cloud Run 관리자 및 서비스 계정 사용자 역할을 Cloud Build 서비스 계정에 부여해야 하므로, GCP 콘솔에서 아래 항목들에 대해 관리자 역할의 상태를 사용 설정으로 변경해준다.

 

  • Cloud Run
  • Cloud Build
  • Compute Engine
  • 서비스 계정

 

또한, Cloud Build 사용을 위한 서비스 계정을 생성해준다.

API 및 서비스 > 사용자 인증 정보 > 사용자 인증 정보 만들기 > 서비스 계정에서 진행할 수 있다.

 

 

이후 cloud 빌드(띄어쓰기까지 지켜야함) 라고 검색한 뒤, 관련 권한을 추가해주자.

이 과정이 있어야 정확히 Cloud Build에 접근가능하므로, 빠짐없이 하도록 하자.

 

 


 

1-2. Trigger 생성

Google Cloud Build의 트리거 메뉴에세 CI를 실행할 조건을 생성한다. 

 

 

 

 

1. 저장소가 없는 사람은 소스 코드 저장소를 생성해주면 된다. 이미 생성된 저장소에 연동을 하는 경우라면 저장소 연결을 통해 원격 저장소(Github, Bitbucket 등)를 연결하면 된다. (저장소 관련아래 내용 참고)

 

2. main 브랜치에 push라는 이벤트가 발생하면 트리거를 작동시킬 것이기에, 정규표현식으로 main 브랜치를 입력해준다.

  • 정규 표현식에 대해 잘 모른다면 GPT-4의 도움을 받아도된다. 필자가 지금까지 GPT에게 요청했던 정규표현식은 다 정확했다!

만약 develop에서 분기한 feature/1.4.0-cloudbuild 브랜치라면 이와 같이 작성한다.

 

3. 또한 cloudbuild.yaml로 빌드 관련 세팅을 작성해줄 것이므로 구성 유형은 Cloud Build 구성 파일로 설정한다.

 

 


[저장소] Google Cloud Build와 Bitbucket Cloud 연동

 

 

 

 

깃허브를 쓰는 사람은 제치고....

Bitbucket을 쓰는 사람이라면 여기서 헤맸을 것이다ㅠ.ㅠ(잘 오셨습니다🙇🏻‍♀️🙇🏻‍♀️)

 

 

세 가지 옵션은 각각 다음과 같다.

  1. Bitbucket 서버: Bitbucket에서 제공하는 클라우드 호스팅 서비스로, AWS, GCP와 같은 서비스다.
  2. Bitbucket 데이터 센터: Bitbucket의 상위호환 버전인데... 자세히 알 필요는 없다. 유료 서비스이고, 이걸 이용하는 사람은 이미 나보다 Bitbucket에 대해 잘 알 것이므로 pass.

 

결론

Bitbucket Repository의 소스코드를 빌드에 반영하기위해서 Bitbucket Cloud(미러링)로 설정한다.

이후 저장소 선택으로 넘어가는데, Bitbucket Cloud에 인증이 되었다고 하더라도 초기에 Google Cloud 저장소를 추가해주어야 한다.

 

Bitbucket Cloud 미러링

이 방식은 Bitbucket 저장소를 Cloud Source Repositories에 미러링하는 방식이다. 

 

동작 과정은 다음과 같다.

  1. Bitbucket 저장소로 커밋/푸시
  2. Cloud Source Repositories에서 호스팅된 저장소로 복사 및 미러링
  3. build

 

이와 관련한 자세한 내용은 여기에서 확인할 수 있다.

 

 

Bitbucket 저장소 미러링  |  Cloud Source Repositories 문서  |  Google Cloud

의견 보내기 Bitbucket 저장소 미러링 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 주제에서는 Bitbucket 저장소를 Cloud Source Repositories에 미러링하는 방법을

cloud.google.com

 

 

그리고 반드시 Bitbucket Repository에 대한 admin 권한이 있어야 해당 레포지토리에 접근 가능하므로, 먼저 권한을 체크해보아야 한다. 이렇게 Cloud Build 트리거를 생성한 뒤에는 트리거를 걸어둔 브랜치에 commit/push를 하면서 CI가 잘 되는지 확인해보자. 

 

 

 

Tip. 원격 저장소에 commit / push 날리지 않고 바로 트리거 실행하는 방법 참고

 

[DevOps] Cloud Build 커밋/푸시없이 트리거 실행하기

개요 Cloud Build 작업을 하면서 트리거 테스트를 위해 계속 커밋을 남겼었다. 그런데 공용 Repository에 커밋 및 푸시를 남기지 않고 트리거를 실행하고, 로그를 볼 수 있는 방법을 찾아서 공유한다. G

cobinding.tistory.com

 

 

 

 

 

 

Google Cloud Build > 기록에서 확인할 수 있고, 초록색 체크가 되면 정상적으로 승인이 된 상태이다. 나의 경우 Artifact Registry까지 빌드된 패키지를 전송하는 것으로 작성하였기에 Artifact Registry도 확인해준다. Cloud Build > Artifact Registry > Cloud Run 순서이기 때문

 

 

 

 

작성한 Dockerfile과 cloudbuild.yaml 내용은 다음과 같다.

 

 

Dockerfile

FROM openjdk:17-alpine
ARG JAR_FILE=JAR_FILE_MUST_BE_SPECIFIED_AS_BUILD_ARG
COPY ${JAR_FILE} docker-cicd-test-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java", "-jar", "/docker-cicd-test-0.0.1-SNAPSHOT.jar"]

 

 

cloudbuild.yaml

steps:
  # mvn 설치
  - name: maven:3.8.1-openjdk-17
    entrypoint: mvn
    args: ['package','-Dmaven.test.skip=true' ]

  # 1. 도커 이미지 빌드
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'us-west1-docker.pkg.dev/${PROJECT_ID}/test/${tag}/test:latest', '--build-arg=JAR_FILE=target/docker-cicd-test-0.0.1-SNAPSHOT.jar', '.']

  # 2. Artifact Registry에 푸시하는 단계
  - name: 'gcr.io/cloud-builders/docker'
    args: [ 'push', 'us-west1-docker.pkg.dev/${PROJECT_ID}/test/${tag}/test:latest' ]
            
  # 3. Cloud Run 동작
  # - name: 'gcr.io/cloud-builders/gcloud'
  # - script: |
  #     gcloud run deploy changtalk-run --image us-west1-docker.pkg.dev/quixotic-skill-402605/test/${tag}/test --region us-west2 --platform managed --allow-unauthenticated

options:
  logging: CLOUD_LOGGING_ONLY

 

  • 이 내용은 자신의 projectId와 region 등등 확인 후 작성해야 하므로 복붙은 지양하는 것을 추천
  • Maven 패키지를 도커 컨테이너화하여 빌드 및 배포하므로 docker 명령어를 통한 빌드 및 푸시

 

 

Tip. yaml 파일 작성에 대한 주의점은 이 글에서 확인할 수 있다. 빌드 에러가 났을 때 확인해보면 좋을 듯하다.

 

 

[Backend] yaml 파일 작성법

😮‍💨 새로 CI가 필요한 프로젝트가 있어서 Cloud Build를 구축하는 도충 계속 아래와 같은 에러가 떴다. "failed unmarshalling build config cloudbuild.yaml: yaml: line 3: did not find expected key" yaml 파일 문법 에러

cobinding.tistory.com

 

 


 

2-1. Cloud Run 설정하기

Google Cloud Run이란?

컨테이너를 프로덕션 환경에 배포하는 서버리스 컨테이너 서비스다. 트래픽이 오는 경우에만 작동하도록 설정할 수 있다.(Cloud Build와 함께) 트래픽이 오는 경우에 콜드 스타트가 시작하고 비용이 계산되며, 내부적으로는 Knative라는 것을 사용한다.

 

 

Cloud Run의 소스 저장소에서 지속적으로 새버전 배포를 하면 Cloud Build로 설정을 해야한다고 친절한 UX가 있다. 

아래 안내처럼 소스 저장소 인증을 진행해준다.

 

 

위 동의를 클릭하고 계속 버튼을 누르면 알아서 bitbucket 저장소가 연결된다.

 

 

master -> main으로 변경 

 

배포 자동화를 원하는 저장소와 빌드 구성을 선택해주자.

애플리케이션 코드를 도커 이미지에 생성하여 배포할 것이므로 빌드 유형은 Dockerfile로 생성한다.

또한, 이 Dockerfile은 루트 디렉토리 위치에 있으므로 /Dockerfile으로 경로를 지정해준다

 

 


 

 

  • main 브랜치에 merge/push가되면 자동화를 활성화할 것이므로, CPU는 요청 처리 중에만 할당하도록 한다. (관련 문서: CPU 할당)
  • 인스턴스 개수는 최소를 1로 설정하여 콜드 스타트를 줄이고, 최대는 5로 설정한다. (관련 문서: 최소 인스턴스 설정 문서 )
  • 인그레스 제어는 구글에서 권장하는 내부로 설정해두고 문서를 지속적으로 살펴볼 것. (관련 문서: Cloud Run에 대한 인그레스 제한 

 

 

 

 

Cloud Run에 대한 인그레스 제한  |  Cloud Run 문서  |  Google Cloud

의견 보내기 Cloud Run에 대한 인그레스 제한 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 페이지에서는 인그레스 설정을 사용하여 Cloud Run 서비스에 대

cloud.google.com

 

 

 

 


 

2-2. Cloud Run 주요 세팅에 대한 상세 정보

 

*CPU 할당

비교 요청 처리 중에만 CPU를 할당 항상 CPU를 할당
가격 요청 처리 건에 대해서만 청구 전체 수명 주기 동안 비용 부과
고려사항 수신 트래픽이 산발적이거나 급격하게 증가하는 경우 수신 트래픽이 일정하고 느리게 변화하는 경우
HTTP 응답 반환 후 상황 백그라운드 처리 X 
응답 이전에 모든 걸 처리하도록 설계∙구현 해야함
단기 백그라운드 작업 및 기타 비동기 처리 작업 실행 가능

 

그런데, Google에서는 또 편리하게 1개월 동안 수신 트래픽을 조회하여 어떤 것이 더 좋은지 추천한다.. 그래서 항상 할당된 CPU로 설정한 뒤, 추천자를 세팅해서 추천값을 받으면 최적화할 수 있다! 따라서 일단은 항상 할당됨으로 설정을 하고 추이를 지켜보는 편이 낫겠다. 

 

 

 

*백그라운드 활동

백그라운드 활동HTTP 응답 전달 이후 발생하는 모든 이벤트를 뜻한다. 이러한 백그라운드 활동을 지원하려면 CPU가 항상 할당되도록 설정해야 한다. 그래야만 백그라운드 활동에 대한 CPU 액세스 권한을 유지할 수 있도록 할 수 있기 때문이다. 요청 처리 중에만 CPU가 할당되도록 설정하면, 인스턴스의 CPU 액세스가 사용 중지되거나 제한된다.

따라서 응답을 전달하기 전에 모든 비동기식 작업이 완료되도록 코드를 검토해야 한다.

 

*인스턴스 개수

최소 인스턴스 설정 문서 를 참고하면, 인스턴스 개수는 결국 유휴 인스턴스 사용을 설정하는 방법이다.

Cloud Run은 기본적으로 인스턴스 수에 맞게 확장된다. 또한 요청을 처리하지 않는(유휴 상태) 인스턴스를 삭제한다.

최소 인스턴스는 요청을 처리하지 않는 경우에도 유지하고자 하는 인스턴스 개수이다. 만약 최소 인스턴스를 1으로 세팅하면 서비스가 새 인스턴스를 시작할 필요 없이 구성된 동시 요청 수를 수신할 준비가 되어있다는 뜻이다. (0이면 콜드스타트 시간 필요)

 

 

 

이와 관련해서 Google Cloud에서 일반적인 개발 팁 을 제공한다. 

 

일반적인 개발 팁  |  Cloud Run 문서  |  Google Cloud

의견 보내기 일반적인 개발 팁 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 가이드에서는 Cloud Run 서비스의 설계, 구현, 테스트, 배포를 위한 권장사항

cloud.google.com

 

 

 


 

3-3. 컨테이너, 볼륨, 네트워킹, 보안 설정

 

이후, 컨테이너와 볼륨 등에 대한 설정 화면이 나온다. 이와 관련한 자세한 가이드라인은 여기에 나오니, 필요한 내용들을 잘 숙지하고 작성을 해준다. 

 

 

Cloud Build에 사용될 도커 컨테이너 포트는 기본적으로 8080으로 세팅하고 따로 커스텀화한다면 해당 포트를 잘 연동해준다.

메모리는 괜히 작게 잡았다가 터뜨리지말고 시원하게 크게 잡ㅈ ㅏ!

 

 


요청 시간 제한은 10 분으로 설정하고

인스턴스당 최대 동시요청 수는 기본값인 80으로 세팅하였다. (관련 문서:인스턴스(서비스)당 최대 동시요청)

 

인스턴스(서비스)당 최대 동시 요청  |  Cloud Run 문서  |  Google Cloud

의견 보내기 인스턴스(서비스)당 최대 동시 요청 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Cloud Run 서비스에서 각 버전은 모든 수신 요청을 처리하는

cloud.google.com

 

 

 

4. 생성 완료 및 배포 테스트