Node.js에서 Cloud Run으로 컨테이너 배포 및 실행

Cloud Run은 HTTP 요청으로 호출 가능한 스테이트리스(Stateless) 컨테이너를 실행하는 관리형 컴퓨팅 플랫폼입니다. Cloud Run은 서버리스이므로 인프라 관리가 필요 없습니다. 따라서 개발자가 본연의 업무인 앱 개발에 집중할 수 있습니다. Knative에서 빌드되므로 Cloud Run (완전 관리형) 또는 Cloud Run for Anthos로 컨테이너를 실행할 수 있습니다. 이 Codelab의 목표는 컨테이너 이미지를 빌드하여 Cloud Run에 배포하는 것입니다.

기본 요건

해당 사항 없음

자습형 환경 설정

아직 Google 계정 (Gmail 또는 Google Apps)이 없으면 계정을 만들어야 합니다. Google Cloud Platform 콘솔 (console.cloud.google.com)에 로그인하고 새 프로젝트를 만듭니다.

Screenshot from 2016-02-10 12:45:26.png

모든 Google Cloud 프로젝트에서 고유한 이름인 프로젝트 ID를 기억하세요(위의 이름은 이미 사용되었으므로 사용할 수 없습니다). 이 ID는 나중에 이 Codelab에서 PROJECT_ID라고 부릅니다.

그런 다음 Google Cloud 리소스를 사용할 수 있도록 Cloud 콘솔에서 결제를 사용 설정해야 합니다.

이 codelab을 실행하는 과정에는 많은 비용이 들지 않지만 더 많은 리소스를 사용하려고 하거나 실행 중일 경우 비용이 더 들 수 있습니다(이 문서 마지막의 '삭제' 섹션 참조).

Google Cloud Platform 신규 사용자는 $300 상당의 무료 체험판을 사용할 수 있습니다.

Cloud Shell

Google Cloud는 노트북에서 원격으로 실행할 수 있지만, Google Cloud에서 실행되는 명령줄 환경인 Cloud Shell을 사용합니다.

이 Debian 기반 가상 머신에는 필요한 모든 개발 도구가 로드되어 있습니다. 영구적인 5GB 홈 디렉토리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 즉, 이 Codelab에 필요한 것은 브라우저뿐입니다(Chromebook에서도 작동 가능).

Google Cloud Shell을 활성화하려면 개발자 콘솔에서 오른쪽 상단의 버튼을 클릭합니다. 환경을 프로비저닝하고 연결하는 데 몇 분 정도만 소요됩니다.

activateCloudShell.png

'Cloud Shell 시작' 버튼을 클릭합니다.

Screen Shot 2017-06-14 at 10.13.43 PM.png

Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 내 PROJECT_ID로 설정되어 있음을 확인할 수 있습니다.

gcloud auth list

명령어 결과

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

명령어 결과

[core]
project = <PROJECT_ID>

또한 Cloud Shell은 기본적으로 이후 명령어를 실행할 때 유용할 수 있는 몇 가지 환경 변수를 설정합니다.

echo $GOOGLE_CLOUD_PROJECT

명령어 결과

<PROJECT_ID>

어떤 이유로든 프로젝트가 설정되지 않았으면 다음 명령어를 실행하면 됩니다.

gcloud config set project <PROJECT_ID>

PROJECT_ID를 찾고 계신가요? 설정 단계에서 사용한 ID를 확인하거나 콘솔 대시보드에서 확인하세요.

Project_ID.png

중요: 마지막으로 기본 영역 및 프로젝트 구성을 설정합니다.

gcloud config set compute/zone us-central1-f

다양한 영역을 선택할 수 있습니다. 리전 및 영역 문서에서 자세히 알아보세요.

Cloud Run API를 사용 설정합니다.

Cloud Shell에서 Cloud Run API를 사용 설정합니다.

gcloud services enable run.googleapis.com

그러면 다음과 비슷한 성공 메시지가 표시될 것입니다.

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

HTTP 요청에 응답하는 간단한 표현 기반 Node.js 앱을 빌드합니다.

앱을 빌드하려면 Cloud Shell을 사용하여 helloworld-nodejs이라는 새 디렉터리를 만들고 해당 디렉터리로 디렉터리를 변경합니다.

mkdir helloworld-nodejs
cd helloworld-nodejs

다음 콘텐츠로 package.json 파일을 만듭니다.

{
  "name": "cloudrun-helloworld",
  "version": "1.0.0",
  "description": "Simple hello world sample in Node",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {
    "express": "^4.17.1"
  }
}

가장 중요한 점은 위의 파일에 Express 웹 앱 프레임워크에 대한 종속 항목과 시작 스크립트 명령어가 포함되어 있다는 점입니다.

그런 다음 동일한 디렉터리에서 index.js 파일을 만들고 다음 콘텐츠를 복사하여 붙여넣습니다.

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  console.log('Hello world received a request.');

  const target = process.env.TARGET || 'World';
  res.send(`Hello ${target}!`);
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
  console.log('Hello world listening on port', port);
});

이 코드는 PORT 환경 변수로 정의된 포트를 리슨하는 기본 웹 서버를 만듭니다. 이제 앱을 컨테이너화하고 테스트한 후 Container Registry에 업로드할 수 있습니다.

샘플 앱을 컨테이너화하려면 소스 파일과 동일한 디렉터리에 Dockerfile이라는 새 파일을 만들고 다음 콘텐츠를 복사합니다.

# Use the official lightweight Node.js 12 image.
# https://hub.docker.com/_/node
FROM node:12-slim

# Create and change to the app directory.
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
# Copying this separately prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./

# Run the web service on container startup.
CMD [ "npm", "start" ]

Dockerfile이 포함되어 있는 디렉터리에서 다음 명령어를 실행하여 Cloud Build로 컨테이너 이미지를 빌드합니다.

gcloud builds submit --tag gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

$GOOGLE_CLOUD_PROJECT는 Cloud Shell에서 실행할 때 Google Cloud 프로젝트 ID를 포함하는 환경 변수입니다. gcloud config get-value project를 실행하여 가져올 수도 있습니다.

레지스트리에 푸시되면 이미지 이름 (gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld)이 포함된 SUCCESS 메시지가 표시됩니다. 이미지는 Container Registry에 저장되며 원하는 경우 다시 사용할 수 있습니다.

다음 명령어를 사용하여 현재 프로젝트에 연결된 모든 컨테이너 이미지를 나열할 수 있습니다.

gcloud container images list

Cloud Shell에서 로컬 방식으로 앱을 실행하고 테스트하려면 다음과 같은 표준 docker 명령어를 사용하여 시작합니다.

docker run -d -p 8080:8080 gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

Cloud Shell에서 웹 미리보기를 클릭하고 포트 8080에서 미리보기를 선택합니다.

그러면 Hello World! 라는 메시지가 표시된 브라우저 창이 열립니다.

curl localhost:8080를 사용해도 됩니다.

컨테이너화된 앱을 Cloud Run에 배포하려면 다음 명령어를 사용합니다. 빌드한 앱의 올바른 이미지 이름으로 조정하거나 gcr.io/cloudrun/hello 사전 빌드 이미지를 사용해야 합니다.

gcloud run deploy helloworld \
  --image gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated

--allow-unauthenticated 배포 옵션을 사용하면 인증 없이 앱에 도달할 수 있습니다. --platform managed \ 배포 옵션은 Anthos를 통한 Kubernetes 인프라가 아닌 완전 관리형 환경을 요청하는 것을 의미합니다.

그런 다음 배포가 완료될 때까지 잠시 기다립니다. 완료되면 명령줄에 서비스 URL이 표시됩니다.

Service [helloworld] revision [helloworld-00001] has been deployed
and is serving traffic at https://helloworld-wdl7fdwaaa-uc.a.run.app

이제 웹브라우저에서 서비스 URL을 열어 배포된 컨테이너로 이동할 수 있습니다.

Cloud Run은 수신된 요청을 처리하기 위해 컨테이너 이미지를 자동 및 수평 확장한 다음 수요가 감소하면 축소합니다. 요청 처리 도중 소비한 CPU, 메모리, 네트워킹에 대해서만 비용을 지불하면 됩니다.

Cloud Run에서는 서비스를 사용하지 않을 때 비용이 청구되지 않지만 빌드된 컨테이너 이미지를 저장하는 데 요금이 부과될 수 있습니다.

Google Cloud 프로젝트를 삭제하여 비용 발생을 피하거나(해당 프로젝트에 사용된 모든 리소스에 대한 청구가 중단됨) 간단하게 다음 명령어를 사용하여 helloworld 이미지를 삭제할 수 있습니다.

gcloud container images delete gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

Cloud Run 서비스를 삭제하려면 다음 명령어를 사용합니다.

gcloud run services delete helloworld \
  --platform managed \
  --region us-central1

축하합니다. 컨테이너 이미지로 패키징된 앱을 Cloud Run에 배포했습니다.

자세히 알아보기

다음 단계로 빠른 시작: Cloud Run for Anthos on Google Cloud에 배포를 확인하는 것이 좋습니다.

코드 소스에서 Cloud Run에 적합한 스테이트리스(Stateless) HTTP 컨테이너를 빌드하여 Container Registry로 푸시하는 자세한 과정은 다음 리소스를 참고하세요.

기본 오픈소스 프로젝트인 Knative에 대해 자세히 알아보려면 Knative를 참고하세요.