Compute Engine으로 Google Cloud에서 웹 앱 호스팅 및 확장

1. 소개

Google Cloud에 웹사이트를 배포하는 방법에는 여러 가지가 있으며 각 솔루션은 다양한 기능, 기능, 제어 수준을 제공합니다. Compute Engine은 웹사이트 실행에 사용되는 인프라에 대한 심층적인 제어를 제공하지만 Google Kubernetes Engine, App Engine 등의 솔루션에 비해 운영 관리가 조금 더 필요합니다. Compute Engine을 사용하면 가상 머신, 부하 분산기 등을 포함한 인프라의 여러 측면을 세밀하게 제어할 수 있습니다. 오늘은 Fancy Store의 전자상거래 웹사이트인 샘플 앱을 배포하여 Compute Engine으로 웹사이트를 쉽게 배포하고 확장하는 방법을 보여드리겠습니다.

학습할 내용

Codelab을 마치면 관리형 인스턴스 그룹 내에 인스턴스를 만들어 웹사이트의 자동 복구, 부하 분산, 자동 확장, 순차적 업데이트를 제공합니다.

기본 요건

2. 환경 설정

자습형 환경 설정

  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 상당의 무료 체험판 프로그램에 참여할 수 있는 자격이 부여됩니다.

Compute Engine API 사용 설정

다음으로 Compute Engine API를 사용 설정해야 합니다. API를 사용 설정하려면 API에 대한 서비스 약관 및 청구 책임에 동의해야 합니다.

Cloud Shell에서 다음을 실행하여 Compute Engine API를 사용 설정합니다.

gcloud services enable compute.googleapis.com

Cloud Shell

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

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

  1. Cloud Console에서 Cloud Shell을 활성화하려면 단순히 Cloud Shell 활성화a8460e837e9f5fda.png를 클릭합니다. 환경을 프로비저닝하고 연결하는 데 몇 정도만 소요됩니다.

b532b2f19ab85dda.png

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>

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

gcloud config set project <PROJECT_ID>

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

2485e00c1223af09.png

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

echo $GOOGLE_CLOUD_PROJECT

명령어 결과

<PROJECT_ID>
  1. 마지막으로 기본 영역 및 프로젝트 구성을 설정합니다.
gcloud config set compute/zone us-central1-f

다양한 영역을 선택할 수 있습니다. 자세한 내용은 리전 및 영역을 참조하세요.

Cloud Storage 버킷 만들기

여기서는 Cloud Storage 버킷을 사용하여 빌드된 코드와 시작 스크립트를 저장하겠습니다. Cloud Shell에서 다음 명령어를 실행하여 새 Cloud Storage 버킷을 만듭니다.

gsutil mb gs://fancy-store-$DEVSHELL_PROJECT_ID

3. 소스 저장소 클론

모놀리식 마이크로서비스 저장소를 기반으로 하는 Fancy Store의 기존 전자상거래 웹사이트를 웹사이트의 기반으로 사용합니다. Compute Engine에 배포하는 측면에 집중할 수 있도록 저장소에서 소스 코드를 클론합니다. 나중에 코드를 약간 업데이트하여 Compute Engine에서 간단하게 업데이트할 수 있음을 보여줍니다.

Cloud Shell에서 열기 링크를 통해 코드 저장소를 프로젝트에 자동으로 클론하고 Cloud Shell과 기본 제공 코드 편집기를 열 수 있습니다.

또는 Cloud Shell 내에서 아래 명령어를 사용하여 저장소를 수동으로 클론할 수 있습니다.

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices

Cloud Shell 명령 프롬프트에서 코드의 초기 빌드를 실행하여 앱을 로컬에서 실행할 수 있습니다. 스크립트가 실행되는 데 몇 분 정도 걸릴 수 있습니다.

./setup.sh

실사를 실시하고 앱을 테스트합니다. 다음 명령어를 실행하여 웹 서버를 시작합니다.

cd microservices
npm start

출력:

Products microservice listening on port 8082!
Frontend microservice listening on port 8080!
Orders microservice listening on port 8081!

웹 미리보기 아이콘을 클릭하고 '포트 8080에서 미리보기'를 선택하여 앱을 미리 봅니다.

6634c06dd0b9172c.png

그러면 Fancy Store의 프런트엔드를 볼 수 있는 새 창이 열립니다.

abf2ca314bf80d03.png

웹사이트를 확인한 후 창을 닫아도 됩니다. 웹 서버 프로세스를 중지하려면 터미널 창에서 Control+C (Macintosh의 경우 Command+C)를 누릅니다.

4. Compute Engine 인스턴스 만들기

이제 개발자 환경이 준비되었으므로 Compute Engine 인스턴스를 배포할 수 있습니다. 다음 단계에서는 다음을 수행합니다.

  1. 인스턴스를 구성하는 시작 스크립트를 만듭니다.
  2. 소스 코드를 클론하여 Cloud Storage에 업로드합니다.
  3. Compute Engine 인스턴스를 배포하여 백엔드 마이크로서비스를 호스팅합니다.
  4. 백엔드 마이크로서비스 인스턴스를 활용하도록 프런트엔드 코드를 재구성합니다.
  5. Compute Engine 인스턴스를 배포하여 프런트엔드 마이크로서비스를 호스팅합니다.
  6. 통신을 허용하도록 네트워크를 구성합니다.

시작 스크립트 만들기

시작 스크립트는 인스턴스가 시작될 때마다 수행할 작업을 인스턴스에 지시하는 데 사용됩니다. 이렇게 하면 인스턴스가 자동으로 구성됩니다.

Cloud Shell 리본의 연필 아이콘을 클릭하여 코드 편집기를 엽니다.

monolith-to-microservices 폴더로 이동합니다. 파일 > New File을 만들고 launch-script.sh라는 파일을 만듭니다.

439553c934139b82.png

새 파일에 다음 코드를 붙여넣습니다. 이 중 일부를 붙여넣은 후 수정합니다.

#!/bin/bash

# Install logging monitor. The monitor will automatically pick up logs sent to
# syslog.
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
service google-fluentd restart &

# Install dependencies from apt
apt-get update
apt-get install -yq ca-certificates git build-essential supervisor psmisc

# Install nodejs
mkdir /opt/nodejs
curl https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.gz | tar xvzf - -C /opt/nodejs --strip-components=1
ln -s /opt/nodejs/bin/node /usr/bin/node
ln -s /opt/nodejs/bin/npm /usr/bin/npm

# Get the application source code from the Google Cloud Storage bucket.
mkdir /fancy-store
gsutil -m cp -r gs://fancy-store-[DEVSHELL_PROJECT_ID]/monolith-to-microservices/microservices/* /fancy-store/

# Install app dependencies.
cd /fancy-store/
npm install

# Create a nodeapp user. The application will run as this user.
useradd -m -d /home/nodeapp nodeapp
chown -R nodeapp:nodeapp /opt/app

# Configure supervisor to run the node app.
cat >/etc/supervisor/conf.d/node-app.conf << EOF
[program:nodeapp]
directory=/fancy-store
command=npm start
autostart=true
autorestart=true
user=nodeapp
environment=HOME="/home/nodeapp",USER="nodeapp",NODE_ENV="production"
stdout_logfile=syslog
stderr_logfile=syslog
EOF

supervisorctl reread
supervisorctl update

이제 코드 편집기에서 [DEVSHELL_PROJECT_ID] 텍스트를 찾아 다음 명령어의 출력으로 바꿉니다.

echo $DEVSHELL_PROJECT_ID

출력 예시:

my-gce-codelab-253520

이제 startup-script.sh 코드 줄이 다음과 유사해야 합니다.

gs://fancy-store-my-gce-codelab-253520/monolith-to-microservices/microservices/* /fancy-store/

시작 스크립트는 다음 작업을 수행합니다.

  • syslog에서 로그를 자동으로 수집하는 Logging 에이전트 설치
  • 앱을 데몬으로 실행하는 Node.js 및 Supervisor 설치
  • Cloud Storage 버킷에서 앱의 소스 코드 클론 및 종속 항목 설치
  • 앱을 실행하는 Supervisor의 구성으로, 앱이 예기치 않게 종료되거나 관리자에 의해 중지되는 경우 앱이 다시 시작되는지 확인하고, Logging 에이전트가 수집할 수 있도록 앱의 stdout 및 stderr을 syslog로 전송합니다.

이제 생성된 start-script.sh 파일을 이전에 만든 Cloud Storage 버킷에 복사합니다.

gsutil cp ~/monolith-to-microservices/startup-script.sh gs://fancy-store-$DEVSHELL_PROJECT_ID

이제 https://storage.googleapis.com/[BUCKET_NAME]/startup-script.sh에서 액세스할 수 있습니다. [BUCKET_NAME]은 Cloud Storage 버킷의 이름을 나타냅니다. 기본적으로 승인된 사용자 및 서비스 계정만 볼 수 있으므로 웹브라우저를 통해서는 액세스할 수 없습니다. Compute Engine 인스턴스는 서비스 계정을 통해 자동으로 액세스할 수 있습니다.

Cloud Storage 버킷에 코드 복사

인스턴스가 시작되면 일부 구성 변수를 ‘.env'에 저장할 수 있도록 Cloud Storage 버킷에서 코드를 가져옵니다. 코드 파일을 찾습니다.

클론된 코드를 Cloud Storage 버킷에 복사합니다.

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

백엔드 인스턴스 배포

가장 먼저 배포할 인스턴스가 백엔드 인스턴스가 됩니다. 이 인스턴스에는 주문 및 제품 마이크로서비스가 저장됩니다.

Cloud Shell에서 다음 명령어를 실행하여 나중에 특정 방화벽 규칙을 적용할 수 있도록 이전에 만든 시작 스크립트를 사용하도록 구성되고 백엔드 인스턴스로 태그가 지정된 f1-micro 인스턴스를 만듭니다.

gcloud compute instances create backend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=backend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh

백엔드 연결 구성

앱의 프런트엔드를 배포하기 전에 배포한 백엔드를 가리키도록 구성을 업데이트해야 합니다.

백엔드의 외부 IP 주소를 가져옵니다. 이 주소는 백엔드 인스턴스의 EXTERNAL_IP 탭 아래에 있는 다음 명령어에서 확인할 수 있습니다.

gcloud compute instances list

출력 예시:

NAME     ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
backend  us-central1-a  f1-micro                   10.128.0.2   34.68.223.88  RUNNING

Cloud Shell의 코드 편집기에서 monolith-to-microservices 폴더로 이동합니다. react-app 코드 편집기 메뉴에서 보기 > 숨겨진 파일을 전환하여 .env 파일을 확인합니다.

e7314ceda643e16.png

백엔드의 외부 IP 주소를 가리키도록 .env 파일을 수정합니다. 아래 [BACKEND_ADDRESS]는 gcloud 도구의 이전 명령어로 확인된 백엔드 인스턴스의 외부 IP 주소를 나타냅니다.

REACT_APP_ORDERS_URL=http://[BACKEND_ADDRESS]:8081/api/orders
REACT_APP_PRODUCTS_URL=http://[BACKEND_ADDRESS]:8082/api/products

파일을 저장합니다.

다음 명령어를 사용하여 Rebuild-app을 다시 빌드하면 프런트엔드 코드가 업데이트됩니다.

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

앱 코드를 Cloud Storage 버킷에 복사합니다.

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

프런트엔드 인스턴스 배포

이제 코드가 구성되었으므로 프런트엔드 인스턴스를 배포할 수 있습니다. 다음을 실행하여 이전과 유사한 명령어로 프런트엔드 인스턴스를 배포하지만 이 인스턴스는 'frontend'로 태그가 지정됩니다. 방화벽 용도로도 사용해야 합니다

gcloud compute instances create frontend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=frontend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh 

네트워크 구성

프런트엔드의 경우 포트 8080, 백엔드의 포트 8081 및 8082에 대한 액세스를 허용하는 방화벽 규칙을 만듭니다. 방화벽 명령어는 앱의 인스턴스 생성 중에 할당된 태그를 사용합니다.

gcloud compute firewall-rules create fw-fe \
    --allow tcp:8080 \
    --target-tags=frontend
gcloud compute firewall-rules create fw-be \
    --allow tcp:8081-8082 \
    --target-tags=backend

이제 웹사이트가 작동합니다. 프런트엔드의 외부 IP 주소를 확인합니다. 주소는 프런트엔드 인스턴스의 EXTERNAL_IP를 찾아 확인할 수 있습니다.

gcloud compute instances list

출력 예시:

NAME      ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
backend   us-central1-a  f1-micro                   10.128.0.2   104.198.235.171  RUNNING
frontend  us-central1-a  f1-micro                   10.128.0.3   34.69.141.9      RUNNING

인스턴스를 시작하고 구성하는 데 몇 분 정도 걸릴 수 있습니다. 다음을 실행하여 앱의 준비 상태를 모니터링합니다.

watch -n 5 curl http://[EXTERNAL_IP]:8080 

다음과 비슷한 출력이 표시되면 웹사이트가 준비된 것입니다. 명령 프롬프트에서 Control+C (Macintosh의 경우 Command+C)를 눌러 watch 명령어를 취소합니다.

80dc8721dc08d7e4.png

새로운 웹브라우저 탭에서 http://[FRONTEND_ADDRESS]:8080으로 이동하여 웹사이트에 액세스합니다. 여기서 [FRONTEND_ADDRESS] 는 위에서 결정한 EXTERNAL_IP입니다.

제품 및 주문 페이지로 이동해도 됩니다.

a11460a1fffb07d8.png

5. 관리형 인스턴스 그룹 만들기

애플리케이션이 확장될 수 있도록 관리형 인스턴스 그룹이 생성되고 프런트엔드백엔드 인스턴스를 인스턴스 템플릿으로 사용합니다.

관리형 인스턴스 그룹에는 단일 영역에서 단일 항목으로 관리할 수 있는 동일한 인스턴스가 포함됩니다. 관리형 인스턴스 그룹은 인스턴스를 사용할 수 있는 상태, 즉 RUNNING 상태를 선제적으로 유지하여 앱의 고가용성을 유지합니다. 프런트엔드 및 백엔드 인스턴스에 관리형 인스턴스 그룹을 사용하여 자동 복구, 부하 분산, 자동 확장, 순차적 업데이트를 제공합니다.

소스 인스턴스에서 인스턴스 템플릿 만들기

관리형 인스턴스 그룹을 만들기 전에 그룹의 기반으로 사용할 인스턴스 템플릿을 만들어야 합니다. 인스턴스 템플릿을 사용하면 새 가상 머신 (VM) 인스턴스를 만들 때 사용할 머신 유형, 부팅 디스크 이미지 또는 컨테이너 이미지, 네트워크, 기타 인스턴스 속성을 정의할 수 있습니다. 인스턴스 템플릿을 사용하면 관리형 인스턴스 그룹에 인스턴스를 만들거나 개별 인스턴스를 만들 수도 있습니다.

인스턴스 템플릿을 만들려면 앞서 만든 기존 인스턴스를 사용하세요.

먼저 두 인스턴스를 모두 중지해야 합니다.

gcloud compute instances stop frontend
gcloud compute instances stop backend

이제 소스 인스턴스에서 인스턴스 템플릿을 만듭니다.

gcloud compute instance-templates create fancy-fe \
    --source-instance=frontend
gcloud compute instance-templates create fancy-be \
    --source-instance=backend

인스턴스 템플릿이 생성되었는지 확인합니다.

gcloud compute instance-templates list

출력 예시:

NAME      MACHINE_TYPE  PREEMPTIBLE  CREATION_TIMESTAMP
fancy-be  f1-micro                   2019-09-12T07:52:57.544-07:00
fancy-fe  f1-micro                   2019-09-12T07:52:48.238-07:00

관리형 인스턴스 그룹 만들기

프런트엔드 및 백엔드용으로 하나씩 관리형 인스턴스 그룹 2개를 만듭니다. 이러한 관리형 인스턴스 그룹은 이전에 만든 인스턴스 템플릿을 사용하고 각 그룹의 인스턴스 2개를 시작하도록 구성됩니다. 인스턴스 이름은 'base-instance-name'에 따라 자동으로 지정됩니다. 임의의 문자가 추가된 상태로 지정됩니다.

gcloud compute instance-groups managed create fancy-fe-mig \
    --base-instance-name fancy-fe \
    --size 2 \
    --template fancy-fe
gcloud compute instance-groups managed create fancy-be-mig \
    --base-instance-name fancy-be \
    --size 2 \
    --template fancy-be

애플리케이션의 경우 프런트엔드 마이크로서비스는 포트 8080에서 실행되고 백엔드 마이크로서비스는 주문의 경우 포트 8081에서, 제품의 경우 포트 8082에서 실행됩니다. 표준이 아닌 포트인 경우 식별하기 위해 이름이 지정된 포트를 지정합니다. 이름이 지정된 포트는 서비스 이름과 서비스가 실행되는 포트를 나타내는 키-값 쌍 메타데이터로 인스턴스 그룹에 할당될 수 있습니다. 즉, 그룹의 모든 인스턴스에서 서비스를 이용할 수 있음을 나타냅니다. 이 정보는 나중에 구성할 부하 분산기에서 사용됩니다.

gcloud compute instance-groups set-named-ports fancy-fe-mig \ 
    --named-ports frontend:8080
gcloud compute instance-groups set-named-ports fancy-be-mig \
    --named-ports orders:8081,products:8082

자동 복구 구성

앱 자체의 가용성을 향상시키고 앱이 응답하는지 확인하려면 관리형 인스턴스 그룹에 자동 복구 정책을 구성하면 됩니다.

자동 복구 정책은 앱 기반 상태 확인을 사용하여 앱이 예상대로 응답하는지 확인합니다. 기본 동작인 인스턴스가 RUNNING 상태인지 단순히 확인하는 것보다 앱이 응답하는지 확인하는 것이 더 정확합니다.

프런트엔드와 백엔드에 대해 3회 연속 비정상으로 반환되는 경우 인스턴스를 복구하는 상태 점검을 만듭니다.

gcloud compute health-checks create http fancy-fe-hc \
    --port 8080 \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3
gcloud compute health-checks create http fancy-be-hc \
    --port 8081 \
    --request-path=/api/orders \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3

상태 점검 프로브가 포트 8080 및 8081의 마이크로서비스에 연결하도록 허용하는 방화벽 규칙을 만듭니다.

gcloud compute firewall-rules create allow-health-check \
    --allow tcp:8080-8081 \
    --source-ranges 130.211.0.0/22,35.191.0.0/16 \
    --network default

이 상태 점검을 해당 서비스에 적용합니다.

gcloud compute instance-groups managed update fancy-fe-mig \
    --health-check fancy-fe-hc \
    --initial-delay 300
gcloud compute instance-groups managed update fancy-be-mig \
    --health-check fancy-be-hc \
    --initial-delay 300

Codelab을 계속 진행하여 자동 복구가 그룹의 인스턴스를 모니터링할 때까지 기다립니다. 나중에 자동 복구 테스트 실패를 시뮬레이션합니다.

6. 부하 분산기 만들기

관리형 인스턴스 그룹을 보완하기 위해 HTTP(S) 부하 분산을 사용하여 프런트엔드 및 백엔드 마이크로서비스에 트래픽을 제공하고 매핑을 사용하여 경로 규칙에 따라 적절한 백엔드 서비스로 트래픽을 전송합니다. 이렇게 하면 모든 서비스에 부하가 분산된 단일 IP 주소가 노출됩니다.

Google Cloud에서 사용할 수 있는 부하 분산 옵션에 대한 자세한 내용은 부하 분산 개요를 참조하세요.

HTTP(S) 부하 분산 만들기

Google Cloud는 다양한 유형의 부하 분산을 제공하지만, 트래픽에는 HTTP(S) 부하 분산을 사용합니다. HTTP(S) 부하 분산은 다음과 같이 구성됩니다.

  1. 전달 규칙이 수신되는 요청을 대상 HTTP 프록시로 보냅니다.
  2. 대상 HTTP 프록시는 각 요청과 URL 맵을 대조해 요청에 맞는 백엔드 서비스를 결정합니다.
  3. 백엔드 서비스는 각 요청을 연결된 백엔드의 처리 용량, 영역, 인스턴스 상태를 바탕으로 적절한 백엔드로 보냅니다. HTTP 상태 점검을 사용하여 각 백엔드 인스턴스의 상태를 확인합니다. 백엔드 서비스가 HTTPS 또는 HTTP/2 상태 확인을 사용하도록 구성된 경우 요청은 백엔드 인스턴스로 가는 도중에 암호화됩니다.
  4. 부하 분산기와 인스턴스 간의 세션은 HTTP, HTTPS 또는 HTTP/2 프로토콜을 사용할 수 있습니다. HTTPS 또는 HTTP/2를 사용하는 경우 백엔드 서비스의 각 인스턴스에 SSL 인증서가 있어야 합니다.

각 서비스에 대해 트래픽을 제공할 수 있는 인스턴스를 결정하는 데 사용할 상태 확인을 만듭니다.

gcloud compute http-health-checks create fancy-fe-frontend-hc \
  --request-path / \
  --port 8080
gcloud compute http-health-checks create fancy-be-orders-hc \
  --request-path /api/orders \
  --port 8081
gcloud compute http-health-checks create fancy-be-products-hc \
  --request-path /api/products \
  --port 8082

부하 분산된 트래픽의 대상인 백엔드 서비스를 만듭니다. 백엔드 서비스는 생성된 상태 점검 및 이름이 지정된 포트를 사용합니다.

gcloud compute backend-services create fancy-fe-frontend \
  --http-health-checks fancy-fe-frontend-hc \
  --port-name frontend \
  --global
gcloud compute backend-services create fancy-be-orders \
  --http-health-checks fancy-be-orders-hc \
  --port-name orders \
  --global
gcloud compute backend-services create fancy-be-products \
  --http-health-checks fancy-be-products-hc \
  --port-name products \
  --global

백엔드 서비스를 추가합니다.

gcloud compute backend-services add-backend fancy-fe-frontend \
  --instance-group fancy-fe-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-orders \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-products \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global

URL 맵을 만듭니다. URL 맵은 소스 URL과 이 URL을 전달할 타겟 백엔드 서비스를 정의합니다.

gcloud compute url-maps create fancy-map \
  --default-service fancy-fe-frontend

/api/orders 및 /api/products 경로를 해당 서비스로 라우팅할 수 있도록 경로 일치자를 만듭니다.

gcloud compute url-maps add-path-matcher fancy-map \
   --default-service fancy-fe-frontend \
   --path-matcher-name orders \
   --path-rules "/api/orders=fancy-be-orders,/api/products=fancy-be-products"

생성된 URL 맵에 연결되는 프록시를 만듭니다.

gcloud compute target-http-proxies create fancy-proxy \
  --url-map fancy-map

공개 IP 주소와 포트를 프록시에 연결하는 전역 전달 규칙을 만듭니다.

gcloud compute forwarding-rules create fancy-http-rule \
  --global \
  --target-http-proxy fancy-proxy \
  --ports 80

구성 업데이트

이제 새 고정 IP 주소가 있으므로 이전에 사용한 임시 주소 대신 백엔드 인스턴스를 가리키는 대신 새 주소를 가리키도록 프런트엔드의 코드를 업데이트해야 합니다.

Cloud Shell에서 구성이 포함된 .env 파일이 있는 Rereact-app 폴더로 변경합니다.

cd ~/monolith-to-microservices/react-app/

부하 분산기의 IP 주소를 찾습니다.

gcloud compute forwarding-rules list --global

출력 예시:

NAME                    REGION  IP_ADDRESS     IP_PROTOCOL  TARGET
fancy-http-rule          34.102.237.51  TCP          fancy-proxy

원하는 텍스트 편집기 (예: GNU nano)로 .env 파일을 수정하여 부하 분산기의 공개 IP 주소를 가리킵니다. [LB_IP]는 백엔드 인스턴스의 외부 IP 주소를 나타냅니다.

REACT_APP_ORDERS_URL=http://[LB_IP]/api/orders
REACT_APP_PRODUCTS_URL=http://[LB_IP]/api/products

Rebuild 앱을 다시 빌드하면 프런트엔드 코드가 업데이트됩니다.

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

애플리케이션 코드를 GCS 버킷에 복사합니다.

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

프런트엔드 인스턴스 업데이트

이제 관리형 인스턴스 그룹의 프런트엔드 인스턴스가 새 코드를 가져오도록 하려고 합니다. 인스턴스는 시작 시 코드를 가져오므로 순차적 재시작 명령어를 실행할 수 있습니다.

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable 100%

웹사이트 테스트

rolling-action launch 명령어를 실행한 후 인스턴스가 처리될 때까지 약 30초 정도 기다립니다. 그런 다음 인스턴스가 목록에 나타날 때까지 관리형 인스턴스 그룹의 상태를 확인합니다.

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

항목이 목록에 표시되면 Control+C (Macintosh의 경우 Command+C)를 눌러 시계 명령어를 종료합니다.

서비스가 정상으로 표시되는지 확인합니다.

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

출력 예시:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

항목이 목록에 표시되면 Control+C (Macintosh의 경우 Command+C)를 눌러 watch 명령어를 종료합니다.

그러면 http://[LB_IP]를 통해 애플리케이션에 액세스할 수 있습니다. 여기서 [LB_IP] 는 부하 분산기에 지정된 IP_ADDRESS이며 다음 명령어로 확인할 수 있습니다.

gcloud compute forwarding-rules list --global

7. Compute Engine 확장

지금까지 각각 2개의 인스턴스가 포함된 관리형 인스턴스 그룹 2개를 만들었습니다. 구성은 온전히 작동하지만 로드와 상관없이 정적 구성은 유지됩니다. 이제 사용률을 기준으로 자동 확장 정책을 만들어 각 관리형 인스턴스 그룹을 자동으로 확장해 보겠습니다.

사용률을 기준으로 자동 크기 조정

자동 확장 정책을 만들려면 Cloud Shell에서 다음 명령어를 실행합니다. 부하 분산기의 사용률이 60% 를 넘으면 인스턴스를 자동으로 추가하고 부하 분산기의 사용률이 60% 보다 낮으면 인스턴스를 삭제하는 자동 확장 처리를 관리형 인스턴스 그룹에 만듭니다.

gcloud compute instance-groups managed set-autoscaling \
  fancy-fe-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60
gcloud compute instance-groups managed set-autoscaling \
  fancy-be-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60

콘텐츠 전송 네트워크 사용 설정

확장에 도움이 되는 또 다른 기능은 콘텐츠 전송 네트워크 서비스인 Cloud CDN이 프런트엔드 서비스에 캐싱을 제공하도록 사용 설정하는 것입니다. 이를 위해서는 프런트엔드 서비스에서 다음 명령어를 실행하면 됩니다.

gcloud compute backend-services update fancy-fe-frontend \
    --enable-cdn --global

이제 사용자가 부하 분산기에 콘텐츠를 요청하면 요청이 Google 프런트엔드에 도착합니다. Google 프런트엔드는 먼저 Cloud CDN 캐시를 통해 사용자 요청에 대한 응답을 찾습니다. 프런트엔드가 캐시된 응답을 찾으면 캐시된 응답을 사용자에게 보냅니다. 이것을 캐시 적중이라고 합니다.

그렇지 않고 프런트엔드가 요청에 대해 캐시된 응답을 찾을 수 없는 경우에는 백엔드로 직접 요청을 실행합니다. 요청에 대한 응답이 캐시 가능한 경우 프런트엔드는 응답을 Cloud CDN 캐시에 저장하여 이후 요청에 이 캐시가 사용될 수 있도록 합니다.

8. 웹사이트 업데이트

인스턴스 템플릿 업데이트

기존 인스턴스 템플릿은 수정할 수 없습니다. 하지만 인스턴스가 스테이트리스(Stateless)이고 모든 구성이 시작 스크립트를 통해 이루어지므로, 템플릿 설정 핵심 이미지 자체를 변경하려는 경우에만 인스턴스 템플릿을 변경하면 됩니다. 이제 더 큰 머신 유형을 사용하도록 간단하게 변경하여 푸시합니다.

인스턴스 템플릿의 기초 역할을 하는 프런트엔드 인스턴스를 업데이트합니다. 업데이트하는 동안 인스턴스 템플릿 이미지의 업데이트된 버전에 파일을 배치한 다음 인스턴스 템플릿을 업데이트하고, 새 템플릿을 롤아웃하고, 이 파일이 관리형 인스턴스 그룹 인스턴스에 있는지 확인합니다.

f1-micro 표준 머신 유형을 vCPU 4개와 RAM 3,840MiB가 있는 커스텀 머신 유형으로 전환하여 인스턴스 템플릿의 머신 유형을 수정합니다.

Cloud Shell에서 다음 명령어를 실행하여 frontend 인스턴스의 머신 유형을 수정합니다.

gcloud compute instances set-machine-type frontend --machine-type custom-4-3840

새 인스턴스 템플릿을 만듭니다.

gcloud compute instance-templates create fancy-fe-new \
    --source-instance=frontend \
    --source-instance-zone=us-central1-a

업데이트된 인스턴스 템플릿을 관리형 인스턴스 그룹에 롤아웃합니다.

gcloud compute instance-groups managed rolling-action start-update fancy-fe-mig \
    --version template=fancy-fe-new

업데이트 상태를 모니터링합니다.

watch -n 2 gcloud compute instance-groups managed list-instances fancy-fe-mig

RUNNING 상태인 인스턴스가 2개 이상이고 ACTION이 None으로 설정되고 INSTANCE_TEMPLATE을 새 템플릿 이름 (fancy-fe-new)으로 설정한 후 다음 명령어에서 사용할 수 있도록 나열된 머신 중 하나의 이름을 복사합니다.

Control+S (Macintosh의 Command+S)를 호출하여 시계 프로세스를 종료합니다.

다음을 실행하여 가상 머신에서 새 머신 유형 (custom-4-3840)을 사용하고 있는지 확인합니다. 여기서 [VM_NAME] 은 새로 만든 인스턴스입니다.

gcloud compute instances describe [VM_NAME] | grep machineType

예상되는 출력 예시:

machineType: https://www.googleapis.com/compute/v1/projects/project-name/zones/us-central1-f/machineTypes/custom-4-3840

웹사이트 변경

마케팅팀에서 사이트의 홈페이지 변경을 요청했습니다. 마케팅팀은 홈페이지에서 어떤 회사이며 무엇을 판매하는지에 대해 더 많은 정보를 제공해야 한다고 생각합니다. 이 섹션에서는 마케팅팀이 만족할 수 있도록 홈페이지에 텍스트를 추가합니다. 개발자 중 한 명이 이미 index.js.new라는 파일 이름으로 변경사항을 만든 것 같습니다. 파일을 index.js에 복사하면 변경사항이 반영됩니다. 아래 지침에 따라 적절하게 변경하세요.

다음 명령어를 실행하고 업데이트된 파일을 올바른 파일 이름으로 복사한 다음 내용을 출력하여 변경사항을 확인합니다.

cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js

결과 코드는 다음과 같습니다.

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    width: "800px",
    margin: "0 auto",
    padding: theme.spacing(3, 2)
  }
}));
export default function Home() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
        <Typography variant="h5">
          Fancy Fashion &amp; Style Online
        </Typography>
        <br />
        <Typography variant="body1">
          Tired of mainstream fashion ideas, popular trends and societal norms?
          This line of lifestyle products will help you catch up with the Fancy trend and express your personal style.
          Start shopping Fancy items now!
        </Typography>
      </Paper>
    </div>
  );
}

React 구성요소를 업데이트했지만 정적 파일을 생성하려면 React 앱을 빌드해야 합니다. 다음 명령어를 실행하여 React 앱을 빌드한 다음 모놀리식 공개 디렉터리에 복사합니다.

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

그런 다음 코드를 다시 Cloud Storage 버킷에 푸시합니다.

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

순차적 업데이트로 변경사항 푸시

이제 모든 인스턴스를 강제로 다시 시작하여 업데이트를 가져올 수 있습니다.

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable=100%

순차적 작업 재시작 명령어를 실행한 후 인스턴스가 처리될 때까지 약 30초 정도 기다린 다음 인스턴스가 목록에 나타날 때까지 관리형 인스턴스 그룹의 상태를 확인합니다.

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

항목이 목록에 표시되면 Control+S (Macintosh의 경우 Command+S)를 눌러 시계 명령어를 종료합니다.

다음을 실행하여 서비스가 healthy로 표시되는지 확인합니다.

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

출력 예시:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

항목이 목록에 표시되면 Control+S (Macintosh의 경우 Command+S)를 눌러 시계 명령어를 종료합니다.

콘텐츠 전송 네트워크 내에서 캐시된 콘텐츠를 무효화하고 새로운 콘텐츠가 표시되도록 하려면 다음을 실행합니다.

gcloud compute url-maps invalidate-cdn-cache fancy-map \
    --path "/*"

http://[LB_IP] 를 통해 웹사이트로 이동합니다. 여기서 [LB_IP] 는 부하 분산기에 지정된 IP_ADDRESS이며 다음 명령어로 확인할 수 있습니다.

gcloud compute forwarding-rules list --global

이제 새로운 웹사이트 변경사항이 표시됩니다.

b081b8e885bf0723.png

장애 시뮬레이션

상태 점검이 작동하는지 확인하려면 인스턴스에 로그인하고 서비스를 중지합니다. 인스턴스 이름을 찾으려면 다음을 실행합니다.

gcloud compute instance-groups list-instances fancy-fe-mig

여기에서 인스턴스 중 하나에 보안 셸을 적용합니다. 여기서 INSTANCE_NAME은 목록에 있는 인스턴스 중 하나입니다.

gcloud compute ssh [INSTANCE_NAME]

인스턴스에서 supervisorctl을 사용하여 앱을 중지합니다.

sudo supervisorctl stop nodeapp; sudo killall node

인스턴스를 종료합니다.

exit

수리 작업을 모니터링합니다.

watch -n 5 gcloud compute operations list \
--filter='operationType~compute.instances.repair.*'

다음과 같은 출력 예시를 찾아봅니다.

NAME                                                  TYPE                                       TARGET                                 HTTP_STATUS  STATUS  TIMESTAMP
repair-1568314034627-5925f90ee238d-fe645bf0-7becce15  compute.instances.repair.recreateInstance  us-central1-a/instances/fancy-fe-1vqq  200          DONE    2019-09-12T11:47:14.627-07:00

수리가 확인되면 Control+C (Macintosh의 경우 Command+S)하여 watch 명령어를 종료합니다. 이 시점에서 관리형 인스턴스 그룹은 복구를 위해 인스턴스를 다시 생성합니다.

9. 삭제

준비가 되면 수행한 모든 활동을 삭제하는 가장 쉬운 방법은 프로젝트를 삭제하는 것입니다. 프로젝트를 삭제하면 예상치 못한 반복 요금이 발생하지 않도록 Codelab에서 생성된 부하 분산기, 인스턴스, 템플릿 등이 삭제됩니다. Cloud Shell에서 다음을 실행합니다. 여기서 PROJECT_ID는 프로젝트 이름뿐만 아니라 전체 프로젝트 ID입니다.

gcloud projects delete [PROJECT_ID]

삭제하려면 'Y'를 입력하세요. 표시됩니다.

10. 축하합니다.

Compute Engine에서 웹사이트를 배포, 확장, 업데이트했습니다. 지금까지 Compute Engine, 관리형 인스턴스 그룹, 부하 분산, 상태 점검에 관해 알아보았습니다.