아래는 이전 시스템의 배포 과정이다

메인인 Spring Boot는 위와같이 Jenkins를 통해 자동 배포되었고

Redis, MongoDB, Jenkins, SpringBoot, PostgresSQL, Nginx
이 모든 것들이 Azure Virtual Machine에서 Docker 기반으로 돌아가고 있었다.

이러한 환경이 물론 간단한 개발 환경에서는 저렴하고 직관적이나,
동시에 프로덕션 환경으로는 아쉬움이 많은 것은 사실이다.

물론 시스템의 Health Check 또한 진행하고 있었지만
확장의 한계, 장애 포인트의 단일화, 리소스 경쟁 등등의 문제가 발생하기에
이번에 Azure에서 새로이 GCP로 변경하며 관리형 서비스로 전환하고자 한다.
DB 내보내기 (HeidiSQL)

나는 깔끔하게 각 테이블 마다 생성 쿼리를 저장해두고 싶어
하위 경로의 개체 속성을 지정하였다.
간단하고 빠르게 옮기고 싶다면 단일 .SQL 파일 속성을 지정하여도 된다.

그리고 나는 데이터가 작았기 때문에
Cloud SQL의 Cloud SQL Studio를 이용해 데이터를 옮기게 되었다.
방금 생성한 sql 파일 내용을 그대로 붙여넣고 실행하면
간단하게 DB를 옮기는 것을 완료한 것이다.

변화된 배포 구조
이전에는 Jenkins를 이용했지만 이번에는 Cloud build를 이용해볼 것이다.
편한건 기존에 작성한 Dockerfile이 있기에 그대로 이용해도 된다!
Cloud build를 이용 전 Repository 추가 과정, 즉 저장소 추가 과정이 있었는데
그건 클릭 두 번으로 GitHub login을 연결하는 것이었기에 생략되었다.
이후 트리거를 생성해 언제 이 프로젝트가 빌드될 것인지 지정하게 되었다.
트리거 생성을 위해서는 또 서비스 계정(Service account)가 필요했다.
아래 권한 중 유관 문서를 참고하여
Cloud Build 승인 담당자 역할만 추가하였다.

하지만 사진엔 저장소 관리자도 포함되어 있는데,
서비스 계정을 막상 적용하고자 하니
아래처럼 친절히 GCP가 추가 필요 권한을 알려주었기에 추가되었다.
꽤나 권한이 많은데, 배포하는 과정에서 해당 권한이 필요함을 알게되었다

어떻게 빌드 과정을 포함하지 하는 의문에서

아하 yaml 파일로 직접 지정하는구나! 라는 것을 알았다.
이전 Jenkinsfile을 통해 버전 정보나 과정에 대한건 쉽게 차출 할 수 있었고
서버파일 경로에 cloudbuild.yaml 파일을 작성하였다.
yaml 파일 작성의 기본 개념은 이곳을 통해 배울 수 있었다.
그리고 컨테이너 파일 저장할 Artifact Registry를 생성해준다

복잡한 설정이 없이 이렇게 구성될 수 있나...?
하는 많은 의문을 가진채 일단 구성을 마쳐보았다.


그래 쉽게 되면 재미없지 히히히

배포 오류 모음
1)
Artifact Registry 관리자 권한은 배포 중
권한 부족 오류가 나기에 추가해주었다.
denied: Permission "artifactregistry.repositories.uploadArtifacts"
denied on resource "projects/&&&&&&/locations/&&&&&&/repositories/&&&&&&-server"
(or it may not exist)
2)
iam.serviceAccounts.actAs 권한 부족 문제
+ Cloud Run 배포 관련 yaml에서 서비스 어카운트 명시 안 함
# Deployment failed
ERROR: (gcloud.run.deploy) PERMISSION_DENIED:
Permission 'iam.serviceaccounts.actAs' denied on service account 서비스어카운트계정이름@프로젝트이름.iam.gserviceaccount.com (or it may not exist).
This command is authenticated as 서비스어카운트계정이름@프로젝트이름.iam.gserviceaccount.com
which is the active account specified by
the [core/account] property.
.yaml 수정 예제
# Cloud Run 배포
- name: gcr.io/google.com/cloudsdktool/cloud-sdk
entrypoint: gcloud
args:
[
"run",
"deploy",
"이름",
"--image=us-central1-docker.pkg.dev/프로젝트 이름/컨테이너/컨테이너이름:$COMMIT_SHA",
"--region=us-central1",
"--platform=managed",
"--allow-unauthenticated",
"--service-account=서비스 어카운트 계정" **** 이 내용을 명시하지 않았음
]
3)
해당 서버는 8082 포트를 사용하는데,
dockerfile에 expose를 통한 8082포트이 있지만, 환경변수로는 없었고
기본 8080에 요청 보내는 GCP Health Check는 당연히 이를 모르고
이를 yaml에도 기술하지 않았기 때문에 오류가 났다.
ERROR: (gcloud.run.deploy) Revision '내 컨테이너 이름'
is not ready and cannot serve traffic.
The user-provided container failed to start and listen on the port defined provided
by the PORT=8080 environment variable within the allocated timeout.
This can happen when the container port is misconfigured or if the timeout is too short.
The health check timeout can be extended.
Logs for this revision might contain more information.
3-1) 실패
yaml에는 직접적으로 환경 변수를 지정할 수 없다.
"--region=us-central1",
"--platform=managed",
"--allow-unauthenticated",
"--service-account=서비스 어카운트 계정",
"--set-env-vars", *** 이런 느낌으로 추가했었다.
"PORT=8082"
]
ERROR: (gcloud.run.deploy) spec.template.spec.containers[0].env:
The following reserved env names were provided:PORT.
These values are automatically set by the system.
3-2) 해결
https://stackoverflow.com/questions/59324794/google-cloud-run-port
에서 해답을 얻어 Dcoekrfile에 기존에도 expoes는 되어 있었으나
환경변수로 port를 지정해보았다.
...
ENV PORT 8082
EXPOSE 8082
...
4)
아뿔싸 Jenkins에선 .env 파일을 secrest file같은 걸로 관리할 수 있었는데
GCP에서도 적용해야한다.
나는 Secret manager를 사용해 적용하고자 했다
또한 이를 읽을 수 있도록 secretmanager.secretAccessor 권한을 추가했다.

처음에는 이렇게 env파일을 직접 넣었는데 이러면 개별 값을 알기 어렵기 때문에

희망하는 변수 값과 동일하게 해서 하나씩 모두 만들어줬다
이제 이렇게 역할이 많아졌다.

5)
DB에 연결할 수가 없었다...
허용되지 않았기 때문에.....

고정 아웃바운드 IP 주소 | Cloud Run | Google Cloud Documentation
이 페이지는 Cloud Translation API를 통해 번역되었습니다. 의견 보내기 고정 아웃바운드 IP 주소 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 기본적으로 Cloud
docs.cloud.google.com
이 글을 기준으로 차근차근 만들어갔다.
VPC 네트워크 커넥터 생성


Cloud NAT / Cloud Router 생성

# Cloud Run 배포
- name: gcr.io/google.com/cloudsdktool/cloud-sdk
entrypoint: gcloud
args:
[
"run",
"deploy",
"tih-spring-server",
"--image=컨테이너레지스트리_주소",
"--region=us-central1",
"--platform=managed",
"--allow-unauthenticated",
"--service-account=사용할_서비스_어카운트",
"--vpc-connector=커넥터이름", **** 이거랑
"--vpc-egress=all-traffic", **** 이거 추가함
"--set-secrets",
"환경변수1=GCP에_정의한_MasterSecret이름1:latest, \
환경변수2=GCP에_정의한_MasterSecret이름2:latest, \
환경변수3=GCP에_정의한_MasterSecret이름3:latest"
]
여전히 안된다
6)
Cloud SQL 네트워크에서 해당 경로를 승인한다.

그리고 DB 접속 URL Secret Manager 정보를 변경한다.
jdbc:postgresql:///postgres?cloudSqlInstance=프로젝트이름:지역:CloudSQL인스턴스의이름&socketFactory=com.google.cloud.sql.postgres.SocketFactory

엉엉엉엉어어엉엉
해내따 해내따ㅠㅠㅠㅠㅠㅠ

...
'기술 단어장 > Cloud' 카테고리의 다른 글
| [GKE] 난 이 글을 쓰고나면 클러스터 구성중 모르는 키워드는 없을거야! (0) | 2026.01.05 |
|---|---|
| [S3] 네컷 사진관의 개인정보 유출 문제 제안 및 개선 (1) | 2025.11.10 |
| [Azure] 정적 웹 호스팅 비용 절감을 위한 전략 및 자동 배포 과정 오류 처리 (0) | 2025.05.21 |
| [Cloud] SKT의 유심교체 사태로 보는 AWS S3 보안 (0) | 2025.04.28 |
| [Azure] Blob Storage의 구조 및 보안 설정 분석 (0) | 2025.03.27 |
댓글