Cloud Run으로 간단한 3단계로 개발부터 프로덕션까지

1. 소개

애플리케이션 관리가 어려운 이유는 무엇인가요?

큰 이유 중 하나는 개발자가 파트타임 시스템 관리자가 되는 경우가 많기 때문입니다. 프로덕션 등급의 최신 웹 애플리케이션을 개발, 배포, 관리하려면 다음과 같은 문제 (일부)를 고려해 보세요.

4d018476b4a73b47.png

나는 당신에 대해 잘 모르지만, 이 모든 것에 대해 내가 걱정하고 싶지 않습니다. 정말로 생각하고 싶은 것은 애플리케이션 로직입니다.

6dfd143d20e5548b.png

한마디로 Cloud Run의 핵심은 바로 Cloud Run의 핵심입니다. 개발자에게는 앱에 집중할 수 있는 역량을 키우고 관리와 유지보수는 모두 Google이 맡습니다. Google은 이 분야에서 기술을 연마하고 완성하는 데 수백만 시간을 투자해 왔습니다.

위에서 언급한 관리 문제 외에도 다음 사항도 처리해야 합니다.

  • 종속 항목 - 앱이 실행되는 환경은 가능한 경우 테스트 환경과 정확히 일치해야 합니다. 여기에는 운영체제, 지원 라이브러리, 언어 인터프리터 또는 컴파일러, 하드웨어 구성, 기타 여러 요소를 비롯한 여러 측정기준이 포함될 수 있습니다.
  • 배포 - 앱의 로컬 구현에서 인터넷에서 광범위하게 공유되는 앱으로 이동하려면 런타임 환경의 변화, 복잡성의 급격한 향상, 가파른 학습 곡선이 필요한 경우가 많습니다.

Cloud Run이 이를 비롯한 많은 문제를 처리해 줍니다. 제 말을 그대로 믿는 대신 함께 앱을 빌드하면서 몇 가지 간단한 단계만 거치면 로컬 개발 환경에서 프로덕션 등급의 클라우드 앱으로 얼마나 쉽게 전환할 수 있는지 확인해 보겠습니다.

실습할 내용…

  • 간단한 웹 앱을 빌드하고 개발 환경에서 예상대로 실행되는지 확인합니다.
  • 그런 다음 동일한 앱의 컨테이너화된 버전으로 이동합니다. 또한 컨테이너화의 의미와 컨테이너화가 유용한 이유를 살펴보겠습니다.
  • 마지막으로 앱을 클라우드에 배포하고 명령줄과 Google Cloud 콘솔을 사용하여 Cloud Run 서비스를 얼마나 쉽게 관리할 수 있는지 알아보겠습니다.

학습할 내용…

  • Python으로 간단한 웹 서버 앱을 만드는 방법
  • 어디서나 실행되는 Docker 컨테이너에 앱을 패키징하는 방법
  • 누구나 새로 만들어 볼 수 있도록 앱을 클라우드에 배포하는 방법
  • 빌드팩을 사용하여 위 단계를 더욱 간소화하는 방법
  • Google Cloud 명령줄 도구 및 Cloud Console 웹 UI를 사용하는 방법

필요한 항목…

  • 웹브라우저
  • Google 계정

이 실습은 초보자를 포함한 모든 수준의 개발자를 대상으로 합니다. Python을 사용하겠지만, 사용하는 모든 코드를 설명하므로 Python 프로그래밍에 익숙하지 않아도 내용을 이해할 수 있습니다.

2. 설정하기

5110b5081a1e1c49.png

이 섹션에서는 실습을 시작하는 데 필요한 모든 사항을 다룹니다.

자습형 환경 설정

  1. Cloud 콘솔에 로그인하고 새 프로젝트를 만들거나 기존 프로젝트를 다시 사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

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

이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 가이드를 마친 후 비용이 결제되지 않도록 리소스 종료 방법을 알려주는 '삭제' 섹션의 안내를 따르세요. Google Cloud 신규 사용자에게는 미화$300 상당의 무료 체험판 프로그램에 참여할 수 있는 자격이 부여됩니다.

Cloud Shell 시작

이 실습에서는 Google 클라우드에서 실행되는 가상 머신이 호스팅하는 명령어 인터프리터인 Cloud Shell 세션에서 작업합니다. 이 섹션은 사용자의 컴퓨터에서 로컬로 쉽게 실행할 수도 있지만, Cloud Shell을 사용하면 모든 사람이 일관되고 재현 가능한 환경에 액세스할 수 있습니다. 실습을 마치고 로컬 컴퓨터에서 이 섹션을 다시 시도하셔도 됩니다.

704a7b7491bd157.png

Cloud Shell 활성화

  1. Cloud Console에서 Cloud Shell 활성화4292cbf4971c9786.png를 클릭합니다.

bce75f34b2c53987.png

이전에 Cloud Shell을 시작한 적이 없는 경우 기능을 설명하는 중간 화면 (스크롤해야 볼 수 있는 부분)이 표시됩니다. 이 경우 계속을 클릭합니다 (다시 표시되지 않음). 이 일회성 화면은 다음과 같습니다.

70f315d7b402b476.png

Cloud Shell을 프로비저닝하고 연결하는 데 몇 분 정도만 걸립니다.

fbe3a0674c982259.png

가상 머신에는 필요한 개발 도구가 모두 들어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저나 Chromebook만 사용하여 수행할 수 있습니다.

Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 해당 프로젝트 ID로 이미 설정된 것을 볼 수 있습니다.

  1. Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.
gcloud auth list

명령어 결과

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project

명령어 결과

[core]
project = <PROJECT_ID>

또는 다음 명령어로 설정할 수 있습니다.

gcloud config set project <PROJECT_ID>

명령어 결과

Updated property [core/project].

다음 단계에서 작업을 더 쉽게 할 수 있도록 터미널에 몇 가지 환경 변수를 설정합니다.

export PROJ=$GOOGLE_CLOUD_PROJECT 
export APP=hello 
export PORT=8080
export REGION="us-central1"
export TAG="gcr.io/$PROJ/$APP"

API 사용 설정

이후 단계에서는 이러한 서비스가 필요한 위치와 이유를 설명하겠지만, 지금은 다음 명령어를 실행하여 프로젝트에 Cloud Build, Container Registry, Cloud Run 서비스에 대한 액세스 권한을 부여합니다.

gcloud services enable cloudbuild.googleapis.com         \
                       containerregistry.googleapis.com  \
                       run.googleapis.com          

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

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

3. 간단한 웹 앱 빌드

eef530b56b8e93a3.png

먼저 Cloud Shell 패널 상단에 있는 Open Editor 버튼을 클릭합니다. 상태 메시지가 표시됩니다.

9b81c8a37a6bcdd8.png

그러면 Visual Studio Code와 유사한 IDE 환경이 표시됩니다. 여기서 프로젝트 생성, 소스 코드 편집, 프로그램 실행 등의 작업을 수행할 수 있습니다. 화면이 너무 꽉 찬 경우 아래 강조 표시된 두 영역 사이의 가로 막대를 드래그하여 콘솔과 편집/터미널 창 사이의 구분선을 확장하거나 축소할 수 있습니다.

8dea35450851af53.png

Open Editor 버튼과 Open Terminal 버튼을 각각 클릭하여 편집기와 터미널 간에 전환할 수 있습니다. 지금 두 환경 사이를 번갈아 가며 사용해 보세요.

다음으로 파일 > 새 폴더를 선택하고 hello을 입력한 다음 OK를 클릭하여 이 실습의 작업을 저장할 폴더를 만듭니다. 이 실습에서 만든 모든 파일과 Cloud Shell에서 수행하는 모든 작업이 이 폴더에 저장됩니다.

이제 requirements.txt 파일을 만듭니다. 이는 앱이 사용하는 라이브러리를 Python에 알려줍니다. 이 간단한 웹 앱에서는 Flask라는 웹 서버와 gunicorn이라는 웹 서버 프레임워크를 빌드하는 데 널리 사용되는 Python 모듈을 사용합니다. Cloud Editor 창에서 파일->새 파일 메뉴를 클릭하여 새 파일을 만듭니다. 새 파일의 이름을 입력하라는 메시지가 표시되면 requirements.txt를 입력하고 OK 버튼을 누릅니다. 새 파일이 hello 프로젝트 폴더에 있는지 확인합니다.

새 파일에 다음 줄을 입력하여 앱이 Python Flask 패키지와 gunicorn 웹 서버에 종속되도록 지정합니다.

Flask
gunicorn

Cloud 편집기가 변경사항을 자동으로 저장하므로 이 파일을 명시적으로 저장할 필요가 없습니다.

버전 1: Hello world!

같은 방법을 사용하여 main.py이라는 또 다른 새 파일을 만듭니다. 이 파일이 앱의 유일한 기본 Python 소스 파일이 됩니다. 새 파일이 hello 프로젝트 폴더에 있는지 다시 확인합니다.

이 파일에 다음 코드를 삽입합니다.

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

터미널로 다시 전환하고 다음 명령어를 사용하여 프로젝트 폴더로 변경합니다.

cd hello

다음 명령어를 실행하여 프로젝트 종속 항목을 설치합니다.

pip3 install -r requirements.txt

이제 터미널에서 다음 명령어를 실행하여 앱을 실행합니다.

python3 main.py

이 시점에서 앱은 Cloud Shell 세션 전용 가상 머신에서 실행됩니다. Cloud Shell에는 전역 인터넷 어디에서나 가상 머신에서 실행되는 웹 서버 (예: 방금 시작한 서버)에 액세스할 수 있는 프록시 메커니즘이 포함되어 있습니다.

web preview 버튼을 클릭한 후 다음과 같이 Preview on Port 8080 메뉴 항목을 클릭합니다.

fe45e0192080efd6.png

그러면 실행 중인 앱의 웹브라우저 탭이 열리고 다음과 같이 표시됩니다.

b1f06501509aefb9.png

버전 2: URL 경로 에코

Open Editor 버튼을 통해 Cloud 편집기로 돌아가서 다음과 같이 main.py 파일을 업데이트하여 선택적 URL 접미사 에코 지원을 추가합니다.

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])     # ← NEW
def say_hello(name="world"):               # ← MODIFIED
    html = f"<h1>Hello {name}!</h1>"       # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Open Terminal 버튼을 사용하여 터미널로 다시 전환하고 control-C를 입력하고('C' 키를 누른 상태에서 Ctrl 키를 누른 상태에서) 다음을 입력하여 실행 중인 앱을 중지한 후 다시 시작합니다.

python3 main.py

다시 web preview 버튼을 클릭한 후 Preview on Port 8080 메뉴 항목을 클릭하여 실행 중인 앱의 웹브라우저 탭을 엽니다. 그러면 'Hello world!' 메시지를 보내고, 슬래시 문자 다음에 오는 URL 텍스트를 원하는 문자열 (예: /your-name)로 바꾸고 다음과 같은 내용이 표시되는지 확인합니다.

93b87996f88fa370.png

버전 3: 임의의 색상

이제 Open Editor 버튼을 통해 Cloud 편집기로 돌아가서 다음과 같이 main.py 파일을 업데이트하여 임의의 배경 색상 지원을 추가합니다.

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# This function decides whether foreground text should be
# displayed in black or white, to maximize fg/bg contrast.
def set_text_color(rgb):                      # ← NEW
    sum = round(                              # ← NEW
        (int(rgb[0]) * 0.299)                 # ← NEW
        + (int(rgb[1]) * 0.587)               # ← NEW
        + (int(rgb[2]) * 0.114)               # ← NEW
    )                                         # ← NEW
    return "black" if sum > 186 else "white"  # ← NEW


# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
# To verify each new invocation of these requests, the HTML document
# includes CSS styling to produce a randomly colored background.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])
def say_hello(name="world"):
    bg = random.sample(range(1, 255), 3)                       # ← NEW
    hex = (int(bg[0]) * 256) + (int(bg[1]) * 16) + int(bg[2])  # ← NEW
    fg_color = set_text_color(bg)                              # ← NEW
    bg_color = f"#{hex:06x}"                                   # ← NEW
    style = f"color:{fg_color}; background-color:{bg_color}"   # ← NEW
    html = f'<h1 style="{style}">Hello {name}!</h1>'           # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Open Terminal 버튼을 사용하여 터미널로 다시 전환하고 control-C를 입력하고('C' 키를 누른 상태에서 Ctrl 키를 누른 상태에서) 다음을 입력하여 실행 중인 앱을 중지한 후 다시 시작합니다.

python3 main.py

다시 web preview 버튼을 클릭한 후 Preview on Port 8080 메뉴 항목을 클릭하여 실행 중인 앱의 웹브라우저 탭을 엽니다. 생성된 텍스트가 지정된 접미사 또는 기본 'Hello world!'와 함께 표시됩니다. 문자열로, 다음과 같이 무작위로 색상이 지정된 배경 앞에 표시됩니다.

baf8d028f15ea7f4.png

페이지를 몇 번 새로고침하여 앱을 방문할 때마다 임의의 배경 색상이 변경되는지 확인합니다.

이것으로 앱이 완료되었습니다. 축하합니다! 다음 단계에서는 앱을 컨테이너로 패키징하는 방법과 이 방법이 유용한 이유를 알아봅니다.

4. 앱 컨테이너화

17cc234ec3325a8a.png

컨테이너란?

일반적으로 컨테이너, 특히 Docker를 사용하면 모든 종속 항목이 번들로 포함된 애플리케이션을 실행할 수 있는 모듈식 상자를 만들 수 있습니다. 그 결과를 컨테이너 이미지라고 합니다. 이 섹션에서는 애플리케이션 및 모든 종속 항목을 캡슐화하는 데 사용할 컨테이너 이미지를 만듭니다.

종속 항목에 관해 설명하자면 이전 단계에서 개발자 환경에서 앱을 실행할 때 pip3 install -r requirements.txt를 실행하고 requirements.txt 파일에 모든 종속 라이브러리와 상응하는 버전이 포함되어 있는지 확인해야 했습니다. 컨테이너를 사용하면 컨테이너 이미지를 생성할 때 이러한 요구사항을 설치하므로 컨테이너 소비자가 다른 항목 설치를 걱정할 필요가 없습니다.

이 컨테이너 이미지는 Cloud Run에 애플리케이션을 배포하기 위한 기본 구성요소를 형성합니다. 컨테이너는 거의 모든 가상 서버 또는 실제 서버에서 사용할 수 있기 때문에, 컨테이너는 원하는 곳에 애플리케이션을 배포하고, 한 서비스 제공업체에서 다른 서비스 제공업체로 또는 온프레미스에서 클라우드로 애플리케이션을 이전할 수 있는 방법을 제공합니다.

컨테이너는 애플리케이션을 다음과 같이 만드는 데 도움이 됩니다.

  • 재현 가능 - 컨테이너가 독립적이고 완전함
  • 이식성 - 컨테이너는 산업을 넘나드는 빌딩 블록으로, 클라우드 제공업체와 환경 간에 애플리케이션을 이식할 수 있도록 지원합니다.

간단히 말해 컨테이너는 '한 번만 작성하면 어디서나 실행'할 수 있는 기능을 제공합니다. 이 규칙의 한 가지 예외는 생성된 컨테이너가 컨테이너를 만든 프로세서 유형에서 실행되도록 제한되지만 다른 하드웨어 구성을 위한 컨테이너 버전을 생성할 수도 있다는 것입니다.

자, 컨테이너를 만들어 보겠습니다. 여기에서는 Docker라는 특정 기술을 사용하여 컨테이너를 만들게 됩니다.

Cloud 편집기에서 Dockerfile라는 새 파일을 만듭니다. 이 파일은 이미지를 구성하기 위한 청사진입니다. 운영 환경 및 소스 코드, 종속 항목 설치 방법, 앱 빌드, 코드 실행 방법을 Docker에 알려줍니다.

# Use an official lightweight Python image.
FROM python:3.9-slim

# Copy local code to the container image.
WORKDIR /app
COPY main.py .
COPY requirements.txt .

# Install dependencies into this container so there's no need to 
# install anything at container run time.
RUN pip install -r requirements.txt

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here you use the gunicorn
# server, with one worker process and 8 threads. For environments 
# with multiple CPU cores, increase the number of workers to match 
# the number of cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 main:app

Cloud 터미널에서 다음 명령어를 실행하여 Cloud Build로 컨테이너 이미지를 빌드합니다.

gcloud builds submit --tag $TAG

레지스트리로 푸시되면 gcr.io/<project-id>/hello와 같은 이미지 이름이 포함된 SUCCESS 메시지가 표시됩니다. 이제 이미지는 Google Container Registry에 저장되며 언제 어디서나 재사용할 수 있습니다.

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

gcloud container images list

이제 다음 docker 명령어를 사용하여 Cloud Shell에서 로컬로 애플리케이션을 실행하고 테스트합니다.

docker run -p $PORT:$PORT -e PORT=$PORT $TAG

-p $PORT:$PORT 옵션은 호스트 환경의 외부 포트 $PORT (위에서 8080으로 설정됨)을 실행 중인 컨테이너 내의 동일한 포트 번호로 매핑하도록 Docker에 지시합니다. 이렇게 하면 개발자가 작성하는 서버 코드와 앱을 테스트할 때 연결하는 외부 포트 번호가 동일할 수 있지만 (8080) 호스트의 모든 외부 포트를 쉽게 컨테이너 내부의 원하는 내부 포트에 매핑할 수 있지만, 마찬가지로 쉽게 -p 옵션을 사용할 수 있습니다.

-e PORT=$PORT 옵션은 컨테이너 내부에서 실행되는 앱에 $PORT 환경 변수 (위에서 8080으로 설정됨)를 사용할 수 있도록 Docker에 지시합니다.

이제 웹브라우저를 컨테이너 내부에서 실행되는 Python 코드를 가리키도록 하여 앱을 테스트할 준비가 되었습니다. Cloud Shell 창에서 '웹 미리보기'를 클릭합니다. 아이콘을 클릭하고 이전 단계에서 한 것처럼 '포트 8080에서 미리보기'를 선택합니다.

결과가 익숙할 것입니다. Cloud Shell 터미널에서 직접 앱을 실행할 때와 마찬가지로 무작위로 색상이 지정된 배경 앞에 생성된 텍스트가 표시됩니다. 페이지를 몇 번 새로고침하여 앱을 방문할 때마다 임의의 배경 색상이 변경되는지 확인합니다.

축하합니다. 이제 컨테이너화된 버전의 앱을 실행했습니다. 다음 섹션에서는 코드를 전혀 손대지 않고 컨테이너 이미지를 프로덕션 품질의 웹 앱으로 변환합니다.

5. 클라우드로...

1b0665d94750ded6.gif

앱을 컨테이너화했으니 이제 이 놀라운 기능을 다른 모든 사용자들과 공유하고 싶을 것입니다. 이제 앱을 클라우드에 배포해 보겠습니다. 하지만 단순히 공유하는 것 이상의 일을 하고 싶습니다. 다음 사항을 확인하세요.

  • 안정적으로 실행 - 앱을 실행하는 컴퓨터가 다운되는 경우 자동 내결함성을 제공합니다.
  • 자동으로 확장 - 앱이 방대한 양의 트래픽을 처리할 수 있고 사용하지 않을 경우 공간을 자동으로 줄입니다.
  • 사용하지 않는 리소스에 대해 비용을 청구하지 않으므로, 트래픽에 응답하는 동안 사용한 리소스에 대해서만 비용이 청구되므로 비용이 최소화됩니다.
  • 맞춤 도메인 이름을 통해 액세스 가능 - 원클릭 솔루션에 액세스하여 서비스에 맞춤 도메인 이름을 할당할 수 있습니다.
  • 뛰어난 응답 시간을 제공합니다. 콜드 스타트는 응답 속도가 합리적이지만 최소 인스턴스 구성을 지정하여 이를 세부적으로 조정할 수 있습니다.
  • 표준 SSL/TLS 웹 보안을 사용하여 엔드 투 엔드 암호화를 지원합니다. 서비스를 배포할 때 표준 웹 암호화와 이에 상응하는 필수 인증서가 무료로 자동 제공됩니다.

앱을 Google Cloud Run에 배포하면 위의 모든 기능과 그 밖의 이점을 누릴 수 있습니다.

Cloud Run에 앱 배포

먼저 이전 버전과 새 버전을 구분할 수 있도록 앱을 수정하겠습니다. 기본 메시지가 'Hello world!'에서 변경되도록 main.py 파일을 수정하면 됩니다. 'Hello from Cloud Run!'으로 바뀝니다 즉, main.py의 다음 줄을 아래에서 변경합니다.

def say_hello(name="world"):

다음과 같이 변경합니다.

def say_hello(name="from Cloud Run"):

Cloud Run은 리전을 기반으로 합니다. 즉, Cloud Run 서비스를 실행하는 인프라가 특정 리전에 위치해 있으며, 해당 리전 내의 모든 영역에서 중복으로 사용할 수 있도록 Google에서 관리합니다. '설정하기' 위 섹션에서는 REGION 환경 변수를 통해 기본 리전을 정의했습니다.

다음 명령어를 사용하여 컨테이너 이미지를 다시 빌드하고 컨테이너화된 애플리케이션을 Cloud Run에 배포합니다.

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • gcloud config set run/region $REGION로 기본 리전을 정의할 수도 있습니다.
  • --allow-unauthenticated 옵션을 사용하면 서비스를 공개적으로 사용할 수 있습니다. 인증되지 않은 요청을 방지하려면 대신 --no-allow-unauthenticated를 사용하세요.

여기에 지정된 이미지는 이전 단계에서 빌드한 Docker 이미지입니다. Google Container Registry에 결과 이미지를 저장한 Cloud Build 서비스 덕분에 Cloud Run 서비스에서 이를 찾아 배포할 수 있습니다.

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

Deploying container to Cloud Run service [hello] in project [PROJECT_ID...
✓ Deploying new service... Done.                                   
  ✓ Creating Revision... Revision deployment finished. Waiting for health check...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [hello] revision [hello-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-....a.run.app

다음 명령어를 사용하여 서비스 URL을 검색할 수도 있습니다.

gcloud run services describe hello  \
  --platform managed                \
  --region $REGION                  \
  --format "value(status.url)"

다음과 같이 표시됩니다.

https://hello-....a.run.app

이 링크는 TLS 보안이 적용된 Cloud Run 서비스 전용 URL입니다. 이 링크는 서비스를 사용 중지하지 않는 한 영구적이며 인터넷 어디에서나 사용할 수 있습니다. 앞에서 언급했듯이 일시적인 가상 머신에 종속된 Cloud Shell의 프록시 메커니즘은 사용하지 않습니다.

강조표시된 Service URL를 클릭하여 실행 중인 앱의 웹브라우저 탭을 엽니다. 결과에 'Hello from Cloud Run!'이 메시지를 무작위로 색칠한 배경 앞에 놓습니다.

축하합니다. 이제 앱이 Google의 클라우드에서 실행됩니다. TLS (HTTPS) 암호화와 자동 확장 기능을 통해 놀라울 정도로 뛰어난 트래픽 수준으로 자동 확장되는 앱이 공개되므로 걱정할 필요도 없습니다.

하지만 이 과정이 훨씬 쉬울 수도 있다고 생각해요...

6. 자동으로 컨테이너 만들기

꽤 멋지긴 하지만 Dockerfile과 컨테이너에 관해 생각조차 하지 않으려면 어떻게 해야 할까요? 대부분의 개발자처럼 애플리케이션 코드 작성에만 집중하고 다른 사람은 컨테이너화에 대해 걱정할 수 있다면 어떨까요? Cloud Run이 빌드팩이라는 오픈소스 표준을 지원하기 때문에 운이 좋았습니다. 빌드팩은 소스 파일 컬렉션에서 컨테이너 제조 프로세스를 자동화하는 것입니다.

개발자가 명시적 Dockerfile을 사용하는 것을 선호하는 경우도 있습니다. 예를 들어 컨테이너 빌드 방식을 고도로 맞춤설정하려는 경우가 있습니다. 하지만 이 실습과 같은 일반적인 사례에서는 빌드팩이 원활하게 작동하며 Dockerfile를 직접 만들 필요가 없습니다. 빌드팩을 사용하도록 코드를 수정해 보겠습니다.

먼저 이전 버전과 새 버전을 구분할 수 있도록 앱을 수정하겠습니다. 기본 메시지가 'Hello from Cloud Run!'에서 변경되도록 main.py 파일을 수정하면 됩니다. 'Hello from Cloud Run with Buildpacks!'로 변경합니다. 즉, main.py의 다음 줄을 아래에서 변경합니다.

def say_hello(name="from Cloud Run"):

다음과 같이 변경합니다.

def say_hello(name="from Cloud Run with Buildpacks"):

이제 Procfile라는 새 파일을 만들어 빌드팩을 활용해 보겠습니다. Cloud 편집기에서 해당 파일을 만들고 다음 텍스트 한 줄을 삽입합니다.

web: python3 main.py

이렇게 하면 자동 생성된 컨테이너에서 앱을 실행하는 방법을 빌드백 시스템에 알립니다. 이렇게 지시하면 Dockerfile이 더 이상 필요하지 않습니다. 이를 확인하려면 Dockerfile을 삭제하고 Cloud Shell 터미널에서 다음 명령어를 실행합니다.

gcloud beta run deploy "$APP"  \
    --source .                 \
    --platform "managed"       \
    --region "$REGION"         \
    --allow-unauthenticated

이전 단계에서 앱을 배포하기 위해 실행한 명령어와 유사하지만 이번에는 --image 옵션을 --source . 옵션으로 대체했습니다. 이는 현재 디렉터리에서 찾은 소스 파일을 기반으로 빌드팩을 사용하여 컨테이너 이미지를 만들도록 gcloud 명령어에 지시합니다 (--source .dot은 현재 디렉터리의 약어임). 서비스가 암시적으로 컨테이너 이미지를 처리하므로 이 gcloud 명령어에 이미지를 지정할 필요가 없습니다.

강조 표시된 Service URL를 클릭하여 실행 중인 앱의 웹브라우저 탭을 열고 서비스에 'Hello from Cloud Run with Buildpacks!'가 표시되는지 다시 한 번 확인하여 이 배포가 작동하는지 확인합니다. 색깔이 있는 배경 앞에 두기.

빌드팩을 사용하여 Dockerfile를 제조하면 기본적으로 간단한 3단계를 2단계로 줄일 수 있습니다.

  1. 개발 환경에서 앱을 만듭니다.
  2. 명령어 하나로 클라우드에 정확히 동일한 코드를 배포합니다.

7. 명령줄을 사용해야 하나요?

아니요 거의 모든 Google Cloud 서비스와 마찬가지로 Cloud Run과 상호작용하는 방법에는 세 가지가 있습니다.

  • 방금 살펴본 gcloud 명령줄 도구
  • Cloud 콘솔을 통한 리치 웹 사용자 인터페이스로, 직관적인 포인트 앤 클릭 상호작용 스타일을 지원합니다.
  • 프로그래밍 방식: Java, C#, Python, Go, JavaScript, Ruby, C/C++ 등 널리 사용되는 여러 언어에서 사용할 수 있는 Google 클라이언트 라이브러리를 사용합니다.

콘솔 UI를 사용하여 Cloud Run 앱의 추가 인스턴스를 배포해 보겠습니다. 왼쪽 상단 메뉴를 통해 Cloud Run 서비스 방문 페이지로 이동합니다.

e2b4983b38c81796.png

그러면 다음과 같이 Cloud Run 서비스 요약이 표시됩니다.

b335e7bf0a3af845.png

'서비스 만들기'를 클릭합니다 링크를 클릭하면 배포 프로세스를 시작할 수 있습니다.

51f61a8ddc7a4c0b.png

'hello-again'을 입력합니다. 를 서비스 이름으로 지정하고, 기본 배포 플랫폼 및 리전을 선택하고, 'Next'(다음)를 클릭합니다.

8a17baa45336c4c9.png

컨테이너 이미지 URL(gcr.io/cloudrun/hello)을 입력하고(Google에서 테스트용으로 만든 컨테이너) '고급 설정'을 클릭하세요. 사용할 수 있는 여러 구성 설정 중 일부를 확인합니다. 몇 가지만 맞춤설정할 수 있습니다.

  • 포트 번호 및 컨테이너 진입점 (컨테이너 빌드 시 지정된 진입점을 재정의함)
  • 하드웨어: 메모리 및 CPU 수
  • 확장: 최소 및 최대 인스턴스 수
  • 초기화 명령어를
  • 기타: 요청 제한 시간 설정, 컨테이너당 최대 요청 수, HTTP/2

'다음'을 클릭합니다. 버튼을 사용합니다. 다음 대화상자에서 서비스가 트리거되는 방식을 지정할 수 있습니다. '인그레스'에서 '모든 트래픽 허용'을 선택하고 '인증'으로 '인증되지 않은 트래픽 허용'을 선택합니다.

e78281d1cff3418.png

이 설정은 사용자 인증 정보를 지정하지 않고도 공개 인터넷 어디에서나 누구나 Cloud Run 앱에 액세스할 수 있다는 점에서 가장 자유로운 설정입니다. 앱에 더 제한적인 설정을 적용하고 싶을 수도 있지만 이 학습 연습을 위해 간단하게 유지하겠습니다.

이제 Create 버튼을 클릭하여 Cloud Run 서비스를 만듭니다. 몇 초 후 Cloud Run 서비스의 요약 목록에 새 서비스가 표시됩니다. 요약 줄은 몇 가지 주요 구성 설정과 함께 가장 최근의 배포 (날짜/시간 및 작성자)를 제공합니다. 서비스 이름 링크를 클릭하여 새 서비스에 대한 세부정보를 상세히 살펴볼 수 있습니다.

서비스를 확인하려면 아래 예에서 강조표시된 것처럼 요약 페이지 상단 근처에 표시된 URL을 클릭합니다.

6c35cf0636dddc51.png

다음과 같은 결과를 확인할 수 있습니다.

3ba6ab4fe0da1f84.png

이제 새 Cloud Run 서비스를 배포했으므로 REVISIONS 탭을 선택하여 여러 배포를 관리하는 몇 가지 방법을 알아보세요.

2351ee7ec4a356f0.png

콘솔에서 직접 새 버전을 배포하려면 아래 스크린샷 예시에 강조 표시된 EDIT & DEPLOY NEW REVISION 버튼을 클릭하면 됩니다.

a599fa88d00d6776.png

새 버전을 만들려면 해당 버튼을 클릭하세요. 아래와 같이 컨테이너 URL 근처에서 SELECT 버튼을 클릭합니다.

5fd1b1f8e1f11d40.png

팝업 대화상자에서 이전에 Buildpacks를 사용하여 Cloud Build에서 배포한 간단한 웹 앱을 찾은 다음 선택을 클릭합니다. 아래에서 컨테이너 이미지를

gcr.io/<project>/cloud-run-source-deploy

폴더로 이동합니다. 예를 들면 다음과 같습니다.

8a756c6157face3a.png

선택한 후 하단으로 스크롤하여 DEPLOY 버튼을 클릭합니다. 이제 앱의 새 버전을 배포했습니다. 확인하려면 서비스 URL을 다시 방문하여 'Hello from Cloud Run with Buildpacks!'라는 다채로운 색상이 표시되는지 확인합니다. 있습니다.

보시다시피 버전 탭에는 배포한 모든 버전에 대한 요약이 표시되며, 이제 이 서비스에 대해 두 개의 버전이 표시됩니다. 버전 이름 왼쪽에 있는 라디오 버튼을 클릭하여 특정 버전을 선택할 수 있으며 화면 오른쪽에 버전 세부정보 요약이 표시됩니다. 이 버튼을 선택하면 두 개의 버전이 서로 다른 두 컨테이너 이미지에서 파생된 것을 확인할 수 있습니다.

MANAGE TRAFFIC 버튼을 사용하면 지정된 버전으로 전송된 수신 요청의 분산을 수정할 수 있습니다. 특정 버전으로 전송되는 트래픽 양을 미세 조정하는 이 기능은 몇 가지 중요한 사용 사례를 가능하게 합니다.

  • 수신 트래픽의 일부를 사용하여 새 버전의 앱을 카나리아 테스트
  • 문제가 있는 출시 버전의 트래픽을 이전 버전으로 되돌리기
  • A/B 테스트

여기에서 MANAGE TRAFFIC 버튼을 찾으세요.

519d3c22ae028287.png

다음과 같이 50/50 트래픽 분할을 지정하여 두 버전 간에 50/50 트래픽 분할을 구성합니다.

8c37d4f115d9ded4.png

이제 저장 버튼을 클릭하고 서비스 URL을 반복적으로 방문하여 50/50 분할을 확인합니다. 평균적으로 요청의 절반이 현재 버전('Hello from Cloud Run with Buildpacks!')에서 처리되고 절반이 이전 버전('실행 중!')에서 처리되는지 확인합니다.

서비스 세부정보 페이지의 다른 탭에서는 성능, 트래픽, 로그를 모니터링할 수 있는 기능을 제공하며, 이를 통해 서비스가 얼마나 잘 작동하고 잘 작동하는지에 대한 유용한 정보를 얻을 수 있습니다. 또한 '권한'을 통해 서비스에 대한 액세스를 세부적으로 조정할 수도 있습니다. 탭 잠시 이 페이지의 탭을 살펴보고 여기에서 사용할 수 있는 기능을 살펴보세요.

프로그래매틱 인터페이스

앞서 언급했듯이 Cloud Run 서비스를 프로그래매틱 방식으로 생성, 배포, 관리할 수도 있습니다. 수동 작업의 경우 이 옵션은 명령줄 또는 웹 콘솔보다 고급적이지만 Cloud Run 서비스를 자동화하는 데 적합한 방법입니다. 다양한 프로그래밍 언어에서 Google 클라이언트 라이브러리를 사용할 수 있습니다.

8. 앱 테스트

198ada162d1f0bf1.png

이 마지막 단계에서는 인위적인 부하 테스트를 실행하여 앱에 스트레스 테스트를 하고 들어오는 수요에 따라 앱이 어떻게 확장되는지 확인합니다. 여기서는 Cloud Shell에 사전 설치되어 있고 부하 테스트를 실행하고 결과를 제시할 수 있는 hey라는 도구를 사용하겠습니다.

테스트 실행

Cloud Shell 터미널에서 다음 명령어를 실행하여 부하 테스트를 실행합니다.

hey -q 1000 -c 200 -z 30s https://hello-...run.app

명령어 인수는 다음과 같이 해석됩니다.

  • -q 1000 - 초당 약 1,000개의 요청으로 부하를 유도해 봅니다.
  • -c 200 - 병렬 작업자 200개 할당
  • -z 30s - 30초 동안 부하 테스트를 실행합니다.
  • 서비스 URL을 이 명령줄의 마지막 인수로 사용해야 합니다.

테스트 결과는 다음과 같이 표시됩니다.

 Summary:
 Total:        30.2767 secs
 Slowest:      3.3633 secs
 Fastest:      0.1071 secs
 Average:      0.1828 secs
 Requests/sec: 1087.2387
 Total data:   3028456 bytes
 Size/request: 92 bytes

Response time histogram:
 0.107 [1]     |
 0.433 [31346] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 0.758 [1472]  |■■
 1.084 [82]    |
 1.410 [4]     |
...

Latency distribution:
...
 50% in 0.1528 secs
 75% in 0.1949 secs
 90% in 0.2442 secs
 95% in 0.4052 secs
 99% in 0.7062 secs

Details (average, fastest, slowest):
...
 req write:    0.0000 secs, 0.0000 secs, 0.0232 secs
 resp wait:    0.1824 secs, 0.1070 secs, 3.2953 secs
 resp read:    0.0000 secs, 0.0000 secs, 0.0010 secs
Status code distribution:
 [200] 32918 responses

이 요약에서는 다음과 같은 몇 가지 관심 항목을 알 수 있습니다.

  • 30초 동안 32,918건의 요청이 초당 약 1,000의 속도로 전송되었습니다.
  • 오류가 없었습니다 (200 HTTP 응답만).
  • 평균 지연 시간은 180ms였습니다.
  • 최소 지연 시간은 107ms, 최악의 경우 3.3초
  • 90번째 백분위수 지연 시간은 244ms였습니다.

Cloud Run 콘솔에서 METRICS 탭을 확인하면 성능 스토리의 서버 측을 볼 수 있습니다.

e635c6831c468dd3.png

9. 삭제

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

GCP 프로젝트를 삭제하여 요금이 청구되지 않도록 하거나, 해당 프로젝트 내에서 사용된 모든 리소스에 대한 청구가 중지되도록 하거나, 다음 명령어를 사용하여 컨테이너 이미지를 삭제할 수 있습니다.

gcloud container images delete $TAG

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

gcloud run services delete hello --platform managed --region $REGION --quiet
gcloud run services delete hello-again --platform managed --region $REGION --quiet

10. 해냈어요!

9a31f4fdbbf1ddcb.png

수고하셨습니다. 프로덕션 Cloud Run 앱을 빌드하고 배포했습니다. 이 과정에서 컨테이너와 자체 컨테이너 빌드 방법에 대해 배웠습니다. gcloud 명령줄 도구와 Cloud Console을 모두 사용하여 Cloud Run으로 앱을 배포하는 것이 얼마나 쉬운지도 확인했습니다. 이제 멋진 창작물을 전 세계에 공유하는 방법을 알게 되었습니다.

한 가지 중요한 질문을 하겠습니다.

앱이 개발자 환경에서 작동하도록 한 후 Cloud Run에서 제공하는 모든 프로덕션 등급 속성을 포함하여 클라우드에 배포하기 위해 몇 줄의 코드를 수정해야 했나요?

물론 답은 0입니다.

살펴볼 Codelabs...

그 밖의 살펴볼 만한 멋진 기능

참조 문서…

11. 액션 유도하기

Google Cloud 로고

이 Codelab이 만족스러웠고 Google Cloud를 실습하는 시간이 더 길다면 지금 바로 Google Cloud Innovators에 가입해 보세요.

Innovators 일반 회원 배지 로고

Google Cloud Innovators는 무료이며 다음 서비스가 제공됩니다.

  • Google 직원으로부터 직접 최신 소식을 배울 수 있는 실시간 토론, AMA, 로드맵 세션
  • 최신 Google Cloud 소식을 이메일로 받아보세요.
  • 디지털 배지 및 화상 회의 배경
  • 실습 및 Skills Boost 학습 500크레딧 제공

등록하려면 여기를 클릭하세요.