이 문서에서는 Pub/Sub 및 GKE와 마이크로서비스 통합에 설명된 참조 아키텍처를 구현하는 방법을 설명합니다. 이 아키텍처는 컨테이너와 비동기 메시징을 사용하여 장기 실행 프로세스를 처리하도록 설계되었습니다.
이 문서에서는 사진 썸네일을 생성하는 사진 공유 애플리케이션 예시를 사용합니다. Google Kubernetes Engine(GKE)을 사용하여 애플리케이션을 배포하고 Pub/Sub를 사용하여 장기 실행 프로세스를 비동기적으로 호출합니다. 또한 Cloud Storage용 Pub/Sub 알림을 사용하여 애플리케이션 코드를 수정하지 않고 부가 작업을 추가합니다.
이 애플리케이션은 Cloud Build로 컨테이너화되고 Artifact Registry에 저장됩니다. 또한 Cloud Vision을 사용하여 부적절한 이미지를 감지합니다.
아키텍처
다음 다이어그램은 참조 아키텍처를 구현하는 사진 앨범 애플리케이션 예시의 설계를 보여줍니다.
그림 1. 컨테이너 및 비동기 메시징 사용을 기반으로 하는 이미지 처리 아키텍처
위의 다이어그램은 미리보기 이미지 생성 방법을 보여줍니다.
- 클라이언트가 이미지를 애플리케이션에 업로드합니다.
- 애플리케이션이 이미지를 Cloud Storage에 저장합니다.
- 미리보기 이미지 요청이 생성됩니다.
- 미리보기 이미지 생성기가 미리보기 이미지를 생성합니다.
- 성공적으로 응답이 사진 앨범 애플리케이션으로 전송됩니다.
- 성공적으로 응답이 클라이언트로 전송되고 Cloud Storage에서 미리보기 이미지를 확인할 수 있습니다.
다음 다이어그램은 애플리케이션이 비동기적인 방식으로 썸네일 생성을 개별 서비스로 구현하는 방법을 보여줍니다.
그림 2. 썸네일 추출 프로세스의 아키텍처
Pub/Sub를 사용하여 미리보기 이미지 생성 서비스로 서비스 요청을 전송합니다. 이 새 아키텍처는 서비스 호출을 비동기적으로 만듭니다. 따라서 애플리케이션이 클라이언트로 다시 응답을 전송한 후에 썸네일이 백그라운드에서 생성됩니다. 이 설계에서는 썸네일 생성 서비스 확장이 허용되므로 여러 작업이 병렬로 실행될 수 있습니다.
목표
- GKE에 사진 앨범 애플리케이션 예시를 배포합니다.
- 애플리케이션에서 비동기 서비스 호출을 수행합니다.
- Cloud Storage용 Pub/Sub 알림을 사용하여 Cloud Storage 버킷에 새 파일이 업로드되었을 때 애플리케이션을 트리거합니다.
- Pub/Sub를 사용하여 애플리케이션 수정 없이 더 많은 태스크를 수행합니다.
비용
이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.
- Cloud Storage
- Cloud SQL
- Pub/Sub
- GKE에 사용되는 Compute Engine 인스턴스
- GKE 클러스터 관리 수수료
- Cloud Load Balancing
- Cloud Build
- Artifact Registry
- Vision
프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.
예시 애플리케이션 빌드를 마치면 만든 리소스를 삭제하여 비용이 계속 청구되지 않도록 할 수 있습니다. 자세한 내용은 삭제를 참조하세요.
시작하기 전에
- Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
API GKE, Cloud SQL, Cloud Build, Artifact Registry, and Cloud Vision 사용 설정
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
API GKE, Cloud SQL, Cloud Build, Artifact Registry, and Cloud Vision 사용 설정
-
Google Cloud 콘솔에서 Cloud Shell을 활성화합니다.
Google Cloud 콘솔 하단에서 Cloud Shell 세션이 시작되고 명령줄 프롬프트가 표시됩니다. Cloud Shell은 Google Cloud CLI가 사전 설치된 셸 환경으로, 현재 프로젝트의 값이 이미 설정되어 있습니다. 세션이 초기화되는 데 몇 초 정도 걸릴 수 있습니다.
환경 설정
이 섹션에서는 이 문서 전체에 사용되는 값의 기본 설정을 할당합니다. Cloud Shell 세션을 닫으면 이러한 환경 설정이 손실됩니다.
Cloud Shell에서 기본 Google Cloud 프로젝트를 설정합니다.
gcloud config set project PROJECT_ID
PROJECT_ID
를 Google Cloud 프로젝트 ID로 바꿉니다.기본 Compute Engine 리전을 설정합니다.
gcloud config set compute/region REGION export REGION=REGION
REGION
을 사용자에게 가까운 리전으로 바꿉니다. 자세한 내용은 리전 및 영역을 참조하세요.기본 Compute Engine 영역을 설정합니다.
gcloud config set compute/zone ZONE export ZONE=ZONE
ZONE
을 사용자에게 가까운 영역으로 바꿉니다.예제 애플리케이션 파일을 다운로드하여 현재 디렉터리를 설정합니다.
git clone https://github.com/GoogleCloudPlatform/gke-photoalbum-example cd gke-photoalbum-example
Cloud Storage 버킷 만들기 및 기본 썸네일 이미지 업로드
Cloud Shell에서 원래 이미지와 미리보기 이미지를 저장하기 위한 Cloud Storage 버킷을 만듭니다.
export PROJECT_ID=$(gcloud config get-value project) gsutil mb -c regional -l ${REGION} gs://${PROJECT_ID}-photostore
기본 미리보기 이미지 파일을 업로드합니다.
gsutil cp ./application/photoalbum/images/default.png \ gs://${PROJECT_ID}-photostore/thumbnails/default.png
- 업로드된 이미지는
gs://PROJECT_ID-photostore/FILENAME
형식으로 저장됩니다. 여기서FILENAME
은 업로드된 이미지 파일의 이름을 나타냅니다. - 생성된 미리보기 이미지는
gs://PROJECT_ID-photostore/thumbnails/FILENAME
형식으로 저장됩니다. - 원래 이미지 및 해당 미리보기 이미지 모두
FILENAME
값이 동일하지만, 미리보기 이미지는thumbnails
버킷에 저장됩니다. 썸네일을 생성할 때는 사진 앨범 애플리케이션에 다음
default.png
자리표시자 썸네일 이미지가 표시됩니다.
- 업로드된 이미지는
미리보기 이미지 파일을 공개로 설정합니다.
gsutil acl ch -u AllUsers:R \ gs://${PROJECT_ID}-photostore/thumbnails/default.png
Cloud SQL 인스턴스 및 MySQL 데이터베이스 만들기
Cloud Shell에서 Cloud SQL 인스턴스를 만듭니다.
gcloud sql instances create photoalbum-db --region=${REGION} \ --database-version=MYSQL_8_0
연결 이름을 검색합니다.
gcloud sql instances describe photoalbum-db \ --format="value(connectionName)"
나중에 사용하므로 이름을 기록해 둡니다.
root@%
MySQL 사용자의 비밀번호를 설정합니다.gcloud sql users set-password root --host=% --instance=photoalbum-db \ --password=PASSWORD
PASSWORD
를root@%
사용자의 보안 비밀번호로 바꿉니다.Cloud SQL 인스턴스에 연결합니다.
gcloud sql connect photoalbum-db --user=root --quiet
메시지가 표시되면 이전 단계에서 설정한 비밀번호를 입력합니다.
사용자가
appuser
이고 비밀번호가pas4appuser
인photo_db
라는 데이터베이스를 만듭니다.create database photo_db; create user 'appuser'@'%' identified by 'pas4appuser'; grant all on photo_db.* to 'appuser'@'%' with grant option; flush privileges;
결과를 확인하고 MySQL을 종료합니다.
show databases; select user from mysql.user; exit
출력에서
photo_db
데이터베이스 및appuser
사용자가 생성되었는지 확인합니다.mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | photo_db | | sys | +--------------------+ 5 rows in set (0.16 sec) mysql> \t Outfile disabled. mysql> select user from mysql.user; +-------------------+ | user | +-------------------+ | appuser | | cloudsqlreplica | | cloudsqlsuperuser | | root | | cloudsqlexport | | cloudsqlimport | | cloudsqloneshot | | root | | cloudsqlexport | | cloudsqlimport | | cloudsqloneshot | | root | | cloudsqlapplier | | cloudsqlimport | | mysql.infoschema | | mysql.session | | mysql.sys | | root | +-------------------+ 18 rows in set (0.16 sec) mysql> exit Bye
Pub/Sub 주제 및 구독 만들기
Cloud Shell에서
thumbnail-service
라는 Pub/Sub 주제를 만듭니다.gcloud pubsub topics create thumbnail-service
사진 앨범 애플리케이션은
thumbnail-service
주제에 메시지를 게시하여 썸네일 생성 서비스에 요청을 전송합니다.thumbnail-workers
라는 Pub/Sub 구독을 만듭니다.gcloud pubsub subscriptions create --topic thumbnail-service thumbnail-workers
미리보기 이미지 생성 서비스가
thumbnail-workers
구독으로부터 요청을 수신합니다.
GKE 클러스터 만들기
Cloud Shell에서 API 호출 권한이 있는 GKE 클러스터를 만듭니다.
gcloud container clusters create "photoalbum-cluster" \ --scopes "https://www.googleapis.com/auth/cloud-platform" \ --num-nodes "5"
이후 단계에서
kubectl
명령어를 사용하여 클러스터를 관리할 수 있도록 액세스 사용자 인증 정보를 구성합니다.gcloud container clusters get-credentials photoalbum-cluster
노드 목록을 표시합니다.
kubectl get nodes
출력에서
STATUS
값이Ready
인 노드가 5개 있는지 확인합니다.NAME STATUS ROLES AGE VERSION gke-photoalbum-cluster-default-pool-d637570a-2pfh Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-3rm4 Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-f7l4 Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-qb2z Ready <none> 2m53s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-rvnp Ready <none> 2m54s v1.24.10-gke.2300
Artifact Registry 저장소 만들기
Cloud Shell에서 컨테이너 이미지를 저장할 저장소를 만듭니다.
gcloud artifacts repositories create photoalbum-repo \ --repository-format=docker \ --location=us-central1 \ --description="Docker repository"
애플리케이션 이미지 빌드
텍스트 편집기에서
application/photoalbum/src/auth_decorator.py
파일을 열고 사용자 이름과 비밀번호를 업데이트합니다.USERNAME = 'username' PASSWORD = 'passw0rd'
Cloud Shell에서 Cloud Build 서비스를 사용하여 사진 앨범 애플리케이션 이미지를 빌드합니다.
gcloud builds submit ./application/photoalbum -t \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/photoalbum-app
Cloud Build 서비스를 사용하여
thumbnail-worker
미리보기 이미지 생성 서비스를 위해 이미지를 빌드합니다.gcloud builds submit ./application/thumbnail -t \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/thumbnail-worker
사진 앨범 애플리케이션 배포
Cloud Shell에서 사용자 환경의 값으로 사진 앨범 및 미리보기 이미지 생성기에 맞게 Kubernetes 배포 매니페스트를 업데이트합니다.
connection_name=$(gcloud sql instances describe photoalbum-db \ --format "value(connectionName)") digest_photoalbum=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/photoalbum-app:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_photoalbum}/" \ config/photoalbum-deployment.yaml digest_thumbnail=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/thumbnail-worker:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_thumbnail}/" \ config/thumbnail-deployment.yaml
사진 앨범 애플리케이션 및 썸네일 생성 서비스를 시작하기 위한 배포 리소스를 만듭니다.
kubectl create -f config/photoalbum-deployment.yaml kubectl create -f config/thumbnail-deployment.yaml
애플리케이션에 외부 IP 주소를 할당하기 위한 서비스 리소스를 만듭니다.
kubectl create -f config/photoalbum-service.yaml
포드 결과를 확인합니다.
kubectl get pods
출력에서 각
photoalbum-app
및thumbail-worker
포드에 대해 3개의 포드가 있고STATUS
값이Running
인지 확인합니다.NAME READY STATUS RESTARTS AGE photoalbum-app-555f7cbdb7-cp8nw 2/2 Running 0 2m photoalbum-app-555f7cbdb7-ftlc6 2/2 Running 0 2m photoalbum-app-555f7cbdb7-xsr4b 2/2 Running 0 2m thumbnail-worker-86bd95cd68-728k5 2/2 Running 0 2m thumbnail-worker-86bd95cd68-hqxqr 2/2 Running 0 2m thumbnail-worker-86bd95cd68-xnxhc 2/2 Running 0 2m
thumbnail-worker
포드는thumbnail-workers
구독의 썸네일 생성 요청을 구독합니다. 자세한 내용은 소스 코드에서callback
함수가 사용되는 방법을 참조하세요.서비스 결과를 확인합니다.
kubectl get services
출력에서
photoalbum-service
서비스의EXTERNAL-IP
열에 외부 IP 주소가 있는지 확인합니다. 서비스가 모두 실행될 때까지 몇 분 정도 걸릴 수 있습니다.NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.23.240.1 <none> 443/TCP 20m photoalbum-service LoadBalancer 10.23.253.241 146.148.111.115 80:32657/TCP 2m
외부 IP 주소는 나중에 사용하므로 기록해 둡니다. 이 예시에서는
146.148.111.115
입니다.
사진 앨범 애플리케이션 테스트
웹브라우저에서 배포된 애플리케이션에 액세스하려면 다음 URL로 이동하고 이전에 설정한 사용자 이름과 비밀번호를 입력합니다.
http://EXTERNAL_IP
EXTERNAL_IP
는 이전 단계에서 복사한 IP 주소로 바꿉니다.이미지 파일을 업로드하려면 업로드를 클릭합니다.
썸네일 자리표시자가 화면에 표시됩니다.
백그라운드에서 미리보기 이미지 생성 서비스가 업로드된 이미지의 미리보기 이미지를 생성합니다. 생성된 미리보기 이미지를 보기 위해 Refresh를 클릭합니다. Cloud Vision API가 감지한 이미지 라벨을 추가합니다.
원래 이미지를 보려면 미리보기 이미지를 클릭합니다.
부적절한 이미지 인식 기능 추가
다음 이미지는 Cloud Storage용 Pub/Sub 알림을 사용하여 부적절한 콘텐츠를 감지하는 서비스를 트리거하는 방법을 설명합니다. 이 기능은 부적절한 콘텐츠가 포함된 새 파일이 Cloud Storage 버킷에 저장되었을 때 이미지를 흐리게 표시합니다.
이전 이미지에서 서비스는 Vision API의 세이프서치 인식 기능을 사용하여 이미지 안의 부적절한 콘텐츠를 인식합니다.
사진 애플리케이션이 썸네일 생성기와 이미지 검사기를 비동기식으로 트리거합니다. 따라서 특정 순서로 실행된다는 보장이 없습니다. 이미지가 흐리게 처리되기 전에 썸네일 생성이 수행되면 잠시 동안 부적절한 썸네일이 표시될 수 있습니다. 그러나 곧 이미지 검사기가 부적절한 이미지와 부적절한 썸네일을 모두 흐리게 처리합니다.
Pub/Sub 주제, 구독, 알림 만들기
Cloud Shell에서
safeimage-service
라는 Pub/Sub 주제를 만듭니다.gcloud pubsub topics create safeimage-service
safeimage-workers
라는 Pub/Sub 구독을 만듭니다.gcloud pubsub subscriptions create --topic safeimage-service \ safeimage-workers
새 파일이 Cloud Storage 버킷에 업로드될 때 메시지가
safeimage-service
주제로 전송되도록 Pub/Sub 알림을 구성합니다.gsutil notification create -t safeimage-service -f json \ gs://${PROJECT_ID}-photostore
작업자 이미지 빌드 및 배포
Cloud Shell에서 Cloud Build를 사용하여
safeimage-workers
구독에 대해 컨테이너 이미지를 빌드합니다.gcloud builds submit ./application/safeimage \ -t us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/safeimage-worker
세이프 이미지 서비스를 위해 Kubernetes 배포 매니페스트를 사용자의 Google Cloud 프로젝트 ID, Cloud SQL 연결 이름, 컨테이너 이미지 다이제스트로 바꿉니다.
digest_safeimage=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/safeimage-worker:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_safeimage}/" \ config/safeimage-deployment.yaml
배포 리소스 만들기
safeimage-service
주제를 배포하기 위해safeimage-deployment
라는 배포 리소스 만듭니다.kubectl create -f config/safeimage-deployment.yaml
결과를 확인합니다.
kubectl get pods
출력에서
STATUS
값이Running
인safeimage-worker
포드가 3개 있는지 확인합니다.NAME READY STATUS RESTARTS AGE photoalbum-app-555f7cbdb7-cp8nw 2/2 Running 0 30m photoalbum-app-555f7cbdb7-ftlc6 2/2 Running 0 30m photoalbum-app-555f7cbdb7-xsr4b 2/2 Running 8 30m safeimage-worker-7dc8c84f54-6sqzs 1/1 Running 0 2m safeimage-worker-7dc8c84f54-9bskw 1/1 Running 0 2m safeimage-worker-7dc8c84f54-b7gtp 1/1 Running 0 2m thumbnail-worker-86bd95cd68-9wrpv 2/2 Running 0 30m thumbnail-worker-86bd95cd68-kbhsn 2/2 Running 2 30m thumbnail-worker-86bd95cd68-n4rj7 2/2 Running 0 30m
safeimage-worker
pod는safeimage-workers
구독에서 부적절한 이미지 인식 요청을 구독합니다. 자세한 내용은 소스 코드에서callback
함수가 사용되는 방법을 참조하세요.
부적절한 이미지 인식 기능 테스트
이 섹션에서는 세이프서치 인식 기능이 부적절한 이미지를 흐리게 표시하는지 확인하기 위해 테스트 이미지를 업로드합니다. 테스트 이미지는 좀비로 분장한 여자 사진입니다(Pixaby CC0 라이선스에 따라 라이선스 권한이 부여됨).
- 테스트 이미지를 다운로드합니다.
- 이미지를 업로드하기 위해
http://EXTERNAL_IP
로 이동한 후 Upload를 클릭합니다. 새로고침을 클릭합니다. 애플리케이션에 흐리게 표시된 썸네일이 표시됩니다.
업로드된 이미지도 흐리게 표시되었는지 확인하기 위해 미리보기 이미지를 클릭합니다.
삭제
예시 애플리케이션용으로 만든 Google Cloud 리소스를 유지하지 않으려면 리소스를 삭제해 나중에 요금이 청구되지 않도록 할 수 있습니다. 프로젝트를 완전히 삭제하거나 클러스터 리소스를 삭제한 다음 클러스터를 삭제할 수 있습니다.
프로젝트 삭제
- Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.
- 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
- 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.
개별 리소스 삭제
프로젝트를 삭제하는 대신 생성한 개별 리소스를 삭제할 수 있습니다.
GKE에서 리소스를 삭제합니다.
kubectl delete -f config/safeimage-deployment.yaml kubectl delete -f config/photoalbum-service.yaml kubectl delete -f config/thumbnail-deployment.yaml kubectl delete -f config/photoalbum-deployment.yaml
GKE에서 클러스터를 삭제합니다.
gcloud container clusters delete photoalbum-cluster --quiet
Artifact Registry에서 저장소를 삭제합니다.
gcloud artifacts repositories delete photoalbum-repo --location us-central1 --quiet
Pub/Sub에서 구독 및 주제를 삭제합니다.
gcloud pubsub subscriptions delete safeimage-workers gcloud pubsub topics delete safeimage-service gcloud pubsub subscriptions delete thumbnail-workers gcloud pubsub topics delete thumbnail-service
Cloud SQL 인스턴스를 삭제합니다.
gcloud sql instances delete photoalbum-db --quiet
Cloud Storage 버킷을 삭제합니다.
gsutil rm -r gs://${PROJECT_ID}-photostore gsutil rm -r gs://${PROJECT_ID}_cloudbuild
파일을 삭제합니다.
cd .. rm -rf gke-photoalbum-example
다음 단계
- DevOps에 대한 설명을 읽고 이 참조 아키텍처와 관련된 아키텍처 기능에 대해 자세히 알아보세요.
- DevOps 빠른 점검을 사용하여 업계와 비교되는 자신의 현재 상태를 파악하세요.
- 그 밖의 참조 아키텍처, 다이어그램, 튜토리얼, 권장사항을 알아보려면 클라우드 아키텍처 센터를 확인하세요.